Merge branch 'master' into win32
This commit is contained in:
commit
65291b957a
|
|
@ -7,6 +7,7 @@ Some people ported raylib to other languages in the form of bindings or wrappers
|
|||
| Name | raylib Version | Language | License |
|
||||
| :--------------------------------------------------------------------------------------- | :--------------: | :------------------------------------------------------------------: | :------------------: |
|
||||
| [raylib](https://github.com/raysan5/raylib) | **5.5** | [C/C++](https://en.wikipedia.org/wiki/C_(programming_language)) | Zlib |
|
||||
| [raylib-ada](https://github.com/Fabien-Chouteau/raylib-ada) | **5.5** | [Ada](https://en.wikipedia.org/wiki/Ada_(programming_language)) | MIT |
|
||||
| [raylib-beef](https://github.com/Starpelly/raylib-beef) | **5.5** | [Beef](https://www.beeflang.org) | MIT |
|
||||
| [raybit](https://github.com/Alex-Velez/raybit) | **5.0** | [Brainfuck](https://en.wikipedia.org/wiki/Brainfuck) | MIT |
|
||||
| [raylib-c3](https://github.com/c3lang/vendor/tree/main/libraries/raylib55.c3l) | **5.5** | [C3](https://c3-lang.org) | MIT |
|
||||
|
|
|
|||
572
build.zig
572
build.zig
|
|
@ -14,61 +14,82 @@ comptime {
|
|||
@compileError("Raylib requires zig version " ++ min_ver);
|
||||
}
|
||||
|
||||
pub const emsdk = struct {
|
||||
const zemscripten = @import("zemscripten");
|
||||
|
||||
pub fn shell(b: *std.Build) std.Build.LazyPath {
|
||||
return b.dependency("raylib", .{}).path("src/shell.html");
|
||||
}
|
||||
|
||||
pub const FlagsOptions = struct {
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
asyncify: bool = true,
|
||||
};
|
||||
|
||||
pub fn emccDefaultFlags(allocator: std.mem.Allocator, options: FlagsOptions) zemscripten.EmccFlags {
|
||||
var emcc_flags = zemscripten.emccDefaultFlags(allocator, .{
|
||||
.optimize = options.optimize,
|
||||
.fsanitize = true,
|
||||
});
|
||||
|
||||
if (options.asyncify)
|
||||
emcc_flags.put("-sASYNCIFY", {}) catch unreachable;
|
||||
|
||||
return emcc_flags;
|
||||
}
|
||||
|
||||
pub const SettingsOptions = struct {
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
es3: bool = true,
|
||||
emsdk_allocator: zemscripten.EmsdkAllocator = .emmalloc,
|
||||
};
|
||||
|
||||
pub fn emccDefaultSettings(allocator: std.mem.Allocator, options: SettingsOptions) zemscripten.EmccSettings {
|
||||
var emcc_settings = zemscripten.emccDefaultSettings(allocator, .{
|
||||
.optimize = options.optimize,
|
||||
.emsdk_allocator = options.emsdk_allocator,
|
||||
});
|
||||
|
||||
if (options.es3)
|
||||
emcc_settings.put("FULL_ES3", "1") catch unreachable;
|
||||
emcc_settings.put("USE_GLFW", "3") catch unreachable;
|
||||
emcc_settings.put("EXPORTED_RUNTIME_METHODS", "['requestFullscreen']") catch unreachable;
|
||||
|
||||
return emcc_settings;
|
||||
}
|
||||
|
||||
pub fn emccStep(b: *std.Build, raylib: *std.Build.Step.Compile, wasm: *std.Build.Step.Compile, options: zemscripten.StepOptions) *std.Build.Step {
|
||||
const activate_emsdk_step = zemscripten.activateEmsdkStep(b);
|
||||
|
||||
const emsdk_dep = b.dependency("emsdk", .{});
|
||||
raylib.root_module.addIncludePath(emsdk_dep.path("upstream/emscripten/cache/sysroot/include"));
|
||||
wasm.root_module.addIncludePath(emsdk_dep.path("upstream/emscripten/cache/sysroot/include"));
|
||||
|
||||
const emcc_step = zemscripten.emccStep(b, wasm, options);
|
||||
emcc_step.dependOn(activate_emsdk_step);
|
||||
|
||||
return emcc_step;
|
||||
}
|
||||
|
||||
pub fn emrunStep(
|
||||
b: *std.Build,
|
||||
html_path: []const u8,
|
||||
extra_args: []const []const u8,
|
||||
) *std.Build.Step {
|
||||
return zemscripten.emrunStep(b, html_path, extra_args);
|
||||
}
|
||||
};
|
||||
|
||||
fn setDesktopPlatform(raylib: *std.Build.Step.Compile, platform: PlatformBackend) void {
|
||||
switch (platform) {
|
||||
.glfw => raylib.root_module.addCMacro("PLATFORM_DESKTOP_GLFW", ""),
|
||||
.rgfw => raylib.root_module.addCMacro("PLATFORM_DESKTOP_RGFW", ""),
|
||||
.sdl => raylib.root_module.addCMacro("PLATFORM_DESKTOP_SDL", ""),
|
||||
.android => raylib.root_module.addCMacro("PLATFORM_ANDROID", ""),
|
||||
.drm => {},
|
||||
.win32 => raylib.root_module.addCMacro("PLATFORM_DESKTOP_WIN32", ""),
|
||||
else => {},
|
||||
}
|
||||
}
|
||||
|
||||
fn createEmsdkStep(b: *std.Build, emsdk: *std.Build.Dependency) *std.Build.Step.Run {
|
||||
if (builtin.os.tag == .windows) {
|
||||
return b.addSystemCommand(&.{emsdk.path("emsdk.bat").getPath(b)});
|
||||
} else {
|
||||
return b.addSystemCommand(&.{emsdk.path("emsdk").getPath(b)});
|
||||
}
|
||||
}
|
||||
|
||||
fn emSdkSetupStep(b: *std.Build, emsdk: *std.Build.Dependency) !?*std.Build.Step.Run {
|
||||
const dot_emsc_path = emsdk.path(".emscripten").getPath(b);
|
||||
const dot_emsc_exists = !std.meta.isError(std.fs.accessAbsolute(dot_emsc_path, .{}));
|
||||
|
||||
if (!dot_emsc_exists) {
|
||||
const emsdk_install = createEmsdkStep(b, emsdk);
|
||||
emsdk_install.addArgs(&.{ "install", "latest" });
|
||||
const emsdk_activate = createEmsdkStep(b, emsdk);
|
||||
emsdk_activate.addArgs(&.{ "activate", "latest" });
|
||||
emsdk_activate.step.dependOn(&emsdk_install.step);
|
||||
return emsdk_activate;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from Not-Nik/raylib-zig
|
||||
fn emscriptenRunStep(b: *std.Build, emsdk: *std.Build.Dependency, examplePath: []const u8) !*std.Build.Step.Run {
|
||||
const dot_emsc_path = emsdk.path("upstream/emscripten/cache/sysroot/include").getPath(b);
|
||||
// If compiling on windows , use emrun.bat.
|
||||
const emrunExe = switch (builtin.os.tag) {
|
||||
.windows => "emrun.bat",
|
||||
else => "emrun",
|
||||
};
|
||||
var emrun_run_arg = try b.allocator.alloc(u8, dot_emsc_path.len + emrunExe.len + 1);
|
||||
defer b.allocator.free(emrun_run_arg);
|
||||
|
||||
if (b.sysroot == null) {
|
||||
emrun_run_arg = try std.fmt.bufPrint(emrun_run_arg, "{s}" ++ std.fs.path.sep_str ++ "{s}", .{ emsdk.path("upstream/emscripten").getPath(b), emrunExe });
|
||||
} else {
|
||||
emrun_run_arg = try std.fmt.bufPrint(emrun_run_arg, "{s}" ++ std.fs.path.sep_str ++ "{s}", .{ dot_emsc_path, emrunExe });
|
||||
}
|
||||
const run_cmd = b.addSystemCommand(&.{ emrun_run_arg, examplePath });
|
||||
return run_cmd;
|
||||
}
|
||||
|
||||
/// A list of all flags from `src/config.h` that one may override
|
||||
const config_h_flags = outer: {
|
||||
// Set this value higher if compile errors happen as `src/config.h` gets larger
|
||||
|
|
@ -100,10 +121,20 @@ const config_h_flags = outer: {
|
|||
break :outer flags[0..i].*;
|
||||
};
|
||||
|
||||
pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
||||
fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
||||
var raylib_flags_arr: std.ArrayList([]const u8) = .empty;
|
||||
defer raylib_flags_arr.deinit(b.allocator);
|
||||
|
||||
const raylib = b.addLibrary(.{
|
||||
.name = "raylib",
|
||||
.linkage = options.linkage,
|
||||
.root_module = b.createModule(.{
|
||||
.optimize = optimize,
|
||||
.target = target,
|
||||
.link_libc = true,
|
||||
}),
|
||||
});
|
||||
|
||||
try raylib_flags_arr.appendSlice(
|
||||
b.allocator,
|
||||
&[_][]const u8{
|
||||
|
|
@ -114,7 +145,7 @@ pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize:
|
|||
},
|
||||
);
|
||||
|
||||
if (options.shared) {
|
||||
if (options.linkage == .dynamic) {
|
||||
try raylib_flags_arr.appendSlice(
|
||||
b.allocator,
|
||||
&[_][]const u8{
|
||||
|
|
@ -160,16 +191,6 @@ pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize:
|
|||
try raylib_flags_arr.appendSlice(b.allocator, &config_h_flags);
|
||||
}
|
||||
|
||||
const raylib = b.addLibrary(.{
|
||||
.name = "raylib",
|
||||
.linkage = if (options.shared) .dynamic else .static,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
raylib.linkLibC();
|
||||
|
||||
// No GLFW required on PLATFORM_DRM
|
||||
if (options.platform != .drm) {
|
||||
raylib.addIncludePath(b.path("src/external/glfw/include"));
|
||||
|
|
@ -211,23 +232,22 @@ pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize:
|
|||
.glfw => try c_source_files.append(b.allocator, "src/rglfw.c"),
|
||||
.rgfw, .sdl, .drm, .android, .win32 => {},
|
||||
}
|
||||
raylib.linkSystemLibrary("shcore");
|
||||
raylib.linkSystemLibrary("winmm");
|
||||
raylib.linkSystemLibrary("gdi32");
|
||||
raylib.linkSystemLibrary("opengl32");
|
||||
raylib.root_module.linkSystemLibrary("winmm", .{});
|
||||
raylib.root_module.linkSystemLibrary("gdi32", .{});
|
||||
raylib.root_module.linkSystemLibrary("opengl32", .{});
|
||||
|
||||
setDesktopPlatform(raylib, options.platform);
|
||||
},
|
||||
.linux => {
|
||||
if (options.platform == .drm) {
|
||||
if (options.opengl_version == .auto) {
|
||||
raylib.linkSystemLibrary("GLESv2");
|
||||
raylib.root_module.linkSystemLibrary("GLESv2", .{});
|
||||
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
|
||||
}
|
||||
|
||||
raylib.linkSystemLibrary("EGL");
|
||||
raylib.linkSystemLibrary("gbm");
|
||||
raylib.linkSystemLibrary2("libdrm", .{ .use_pkg_config = .force });
|
||||
raylib.root_module.linkSystemLibrary("EGL", .{});
|
||||
raylib.root_module.linkSystemLibrary("gbm", .{});
|
||||
raylib.root_module.linkSystemLibrary("libdrm", .{ .use_pkg_config = .force });
|
||||
|
||||
raylib.root_module.addCMacro("PLATFORM_DRM", "");
|
||||
raylib.root_module.addCMacro("EGL_NO_X11", "");
|
||||
|
|
@ -262,12 +282,12 @@ pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize:
|
|||
const androidAsmPath = try std.fs.path.join(b.allocator, &.{ androidIncludePath, "/asm-generic" });
|
||||
const androidGluePath = try std.fs.path.join(b.allocator, &.{ androidNdkPathString, "/sources/android/native_app_glue/" });
|
||||
|
||||
raylib.addLibraryPath(.{ .cwd_relative = androidLibPath });
|
||||
raylib.root_module.addLibraryPath(.{ .cwd_relative = androidLibPath });
|
||||
raylib.root_module.addLibraryPath(.{ .cwd_relative = androidApiSpecificPath });
|
||||
raylib.addSystemIncludePath(.{ .cwd_relative = androidIncludePath });
|
||||
raylib.addSystemIncludePath(.{ .cwd_relative = androidArchIncludePath });
|
||||
raylib.addSystemIncludePath(.{ .cwd_relative = androidAsmPath });
|
||||
raylib.addSystemIncludePath(.{ .cwd_relative = androidGluePath });
|
||||
raylib.root_module.addSystemIncludePath(.{ .cwd_relative = androidIncludePath });
|
||||
raylib.root_module.addSystemIncludePath(.{ .cwd_relative = androidArchIncludePath });
|
||||
raylib.root_module.addSystemIncludePath(.{ .cwd_relative = androidAsmPath });
|
||||
raylib.root_module.addSystemIncludePath(.{ .cwd_relative = androidGluePath });
|
||||
|
||||
var libcData: std.ArrayList(u8) = .empty;
|
||||
var aw: std.Io.Writer.Allocating = .fromArrayList(b.allocator, &libcData);
|
||||
|
|
@ -291,15 +311,15 @@ pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize:
|
|||
|
||||
if (options.linux_display_backend == .X11 or options.linux_display_backend == .Both) {
|
||||
raylib.root_module.addCMacro("_GLFW_X11", "");
|
||||
raylib.linkSystemLibrary("GLX");
|
||||
raylib.linkSystemLibrary("X11");
|
||||
raylib.linkSystemLibrary("Xcursor");
|
||||
raylib.linkSystemLibrary("Xext");
|
||||
raylib.linkSystemLibrary("Xfixes");
|
||||
raylib.linkSystemLibrary("Xi");
|
||||
raylib.linkSystemLibrary("Xinerama");
|
||||
raylib.linkSystemLibrary("Xrandr");
|
||||
raylib.linkSystemLibrary("Xrender");
|
||||
raylib.root_module.linkSystemLibrary("GLX", .{});
|
||||
raylib.root_module.linkSystemLibrary("X11", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xcursor", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xext", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xfixes", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xi", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xinerama", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xrandr", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xrender", .{});
|
||||
}
|
||||
|
||||
if (options.linux_display_backend == .Wayland or options.linux_display_backend == .Both) {
|
||||
|
|
@ -311,9 +331,9 @@ pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize:
|
|||
@panic("`wayland-scanner` not found");
|
||||
};
|
||||
raylib.root_module.addCMacro("_GLFW_WAYLAND", "");
|
||||
raylib.linkSystemLibrary("EGL");
|
||||
raylib.linkSystemLibrary("wayland-client");
|
||||
raylib.linkSystemLibrary("xkbcommon");
|
||||
raylib.root_module.linkSystemLibrary("EGL", .{});
|
||||
raylib.root_module.linkSystemLibrary("wayland-client", .{});
|
||||
raylib.root_module.linkSystemLibrary("xkbcommon", .{});
|
||||
waylandGenerate(b, raylib, "wayland.xml", "wayland-client-protocol");
|
||||
waylandGenerate(b, raylib, "xdg-shell.xml", "xdg-shell-client-protocol");
|
||||
waylandGenerate(b, raylib, "xdg-decoration-unstable-v1.xml", "xdg-decoration-unstable-v1-client-protocol");
|
||||
|
|
@ -329,25 +349,25 @@ pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize:
|
|||
},
|
||||
.freebsd, .openbsd, .netbsd, .dragonfly => {
|
||||
try c_source_files.append(b.allocator, "rglfw.c");
|
||||
raylib.linkSystemLibrary("GL");
|
||||
raylib.linkSystemLibrary("rt");
|
||||
raylib.linkSystemLibrary("dl");
|
||||
raylib.linkSystemLibrary("m");
|
||||
raylib.linkSystemLibrary("X11");
|
||||
raylib.linkSystemLibrary("Xrandr");
|
||||
raylib.linkSystemLibrary("Xinerama");
|
||||
raylib.linkSystemLibrary("Xi");
|
||||
raylib.linkSystemLibrary("Xxf86vm");
|
||||
raylib.linkSystemLibrary("Xcursor");
|
||||
raylib.root_module.linkSystemLibrary("GL", .{});
|
||||
raylib.root_module.linkSystemLibrary("rt", .{});
|
||||
raylib.root_module.linkSystemLibrary("dl", .{});
|
||||
raylib.root_module.linkSystemLibrary("m", .{});
|
||||
raylib.root_module.linkSystemLibrary("X11", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xrandr", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xinerama", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xi", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xxf86vm", .{});
|
||||
raylib.root_module.linkSystemLibrary("Xcursor", .{});
|
||||
|
||||
setDesktopPlatform(raylib, options.platform);
|
||||
},
|
||||
.macos => {
|
||||
// Include xcode_frameworks for cross compilation
|
||||
if (b.lazyDependency("xcode_frameworks", .{})) |dep| {
|
||||
raylib.addSystemFrameworkPath(dep.path("Frameworks"));
|
||||
raylib.addSystemIncludePath(dep.path("include"));
|
||||
raylib.addLibraryPath(dep.path("lib"));
|
||||
raylib.root_module.addSystemFrameworkPath(dep.path("Frameworks"));
|
||||
raylib.root_module.addSystemIncludePath(dep.path("include"));
|
||||
raylib.root_module.addLibraryPath(dep.path("lib"));
|
||||
}
|
||||
|
||||
// On macos rglfw.c include Objective-C files.
|
||||
|
|
@ -357,26 +377,18 @@ pub fn compileRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize:
|
|||
.flags = raylib_flags_arr.items,
|
||||
});
|
||||
_ = raylib_flags_arr.pop();
|
||||
raylib.linkFramework("Foundation");
|
||||
raylib.linkFramework("CoreServices");
|
||||
raylib.linkFramework("CoreGraphics");
|
||||
raylib.linkFramework("AppKit");
|
||||
raylib.linkFramework("IOKit");
|
||||
raylib.root_module.linkFramework("Foundation", .{});
|
||||
raylib.root_module.linkFramework("CoreServices", .{});
|
||||
raylib.root_module.linkFramework("CoreGraphics", .{});
|
||||
raylib.root_module.linkFramework("AppKit", .{});
|
||||
raylib.root_module.linkFramework("IOKit", .{});
|
||||
|
||||
setDesktopPlatform(raylib, options.platform);
|
||||
},
|
||||
.emscripten => {
|
||||
if (b.lazyDependency("emsdk", .{})) |dep| {
|
||||
if (try emSdkSetupStep(b, dep)) |emSdkStep| {
|
||||
raylib.step.dependOn(&emSdkStep.step);
|
||||
}
|
||||
|
||||
raylib.addIncludePath(dep.path("upstream/emscripten/cache/sysroot/include"));
|
||||
}
|
||||
|
||||
raylib.root_module.addCMacro("PLATFORM_WEB", "");
|
||||
if (options.opengl_version == .auto) {
|
||||
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES2", "");
|
||||
raylib.root_module.addCMacro("GRAPHICS_API_OPENGL_ES3", "");
|
||||
}
|
||||
},
|
||||
else => {
|
||||
|
|
@ -398,9 +410,9 @@ pub fn addRaygui(b: *std.Build, raylib: *std.Build.Step.Compile, raygui_dep: *st
|
|||
raylib.step.dependOn(&gen_step.step);
|
||||
|
||||
const raygui_c_path = gen_step.add("raygui.c", "#define RAYGUI_IMPLEMENTATION\n#include \"raygui.h\"\n");
|
||||
raylib.addCSourceFile(.{ .file = raygui_c_path });
|
||||
raylib.addIncludePath(raygui_dep.path("src"));
|
||||
raylib.addIncludePath(raylib_dep.path("src"));
|
||||
raylib.root_module.addCSourceFile(.{ .file = raygui_c_path });
|
||||
raylib.root_module.addIncludePath(raygui_dep.path("src"));
|
||||
raylib.root_module.addIncludePath(raylib_dep.path("src"));
|
||||
|
||||
raylib.installHeader(raygui_dep.path("src/raygui.h"), "raygui.h");
|
||||
}
|
||||
|
|
@ -412,7 +424,7 @@ pub const Options = struct {
|
|||
rtext: bool = true,
|
||||
rtextures: bool = true,
|
||||
platform: PlatformBackend = .glfw,
|
||||
shared: bool = false,
|
||||
linkage: std.builtin.LinkMode = .static,
|
||||
linux_display_backend: LinuxDisplayBackend = .Both,
|
||||
opengl_version: OpenglVersion = .auto,
|
||||
android_ndk: []const u8 = "",
|
||||
|
|
@ -430,7 +442,7 @@ pub const Options = struct {
|
|||
.rtext = b.option(bool, "rtext", "Compile with text support") orelse defaults.rtext,
|
||||
.rtextures = b.option(bool, "rtextures", "Compile with textures support") orelse defaults.rtextures,
|
||||
.rshapes = b.option(bool, "rshapes", "Compile with shapes support") orelse defaults.rshapes,
|
||||
.shared = b.option(bool, "shared", "Compile as shared library") orelse defaults.shared,
|
||||
.linkage = b.option(std.builtin.LinkMode, "linkage", "Compile as shared or static library") orelse defaults.linkage,
|
||||
.linux_display_backend = b.option(LinuxDisplayBackend, "linux_display_backend", "Linux display backend to use") orelse defaults.linux_display_backend,
|
||||
.opengl_version = b.option(OpenglVersion, "opengl_version", "OpenGL version to use") orelse defaults.opengl_version,
|
||||
.config = b.option([]const u8, "config", "Compile with custom define macros overriding config.h") orelse &.{},
|
||||
|
|
@ -478,14 +490,7 @@ pub const PlatformBackend = enum {
|
|||
};
|
||||
|
||||
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 lib = try compileRaylib(b, target, optimize, Options.getOptions(b));
|
||||
|
|
@ -508,6 +513,145 @@ pub fn build(b: *std.Build) !void {
|
|||
examples.dependOn(try addExamples("textures", b, target, optimize, lib));
|
||||
}
|
||||
|
||||
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 {
|
||||
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 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_mod = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
exe_mod.addCSourceFile(.{ .file = b.path(path), .flags = &.{} });
|
||||
exe_mod.linkLibrary(raylib);
|
||||
|
||||
const run_step = b.step(name, name);
|
||||
|
||||
if (target.result.os.tag == .emscripten) {
|
||||
const wasm = b.addLibrary(.{
|
||||
.name = name,
|
||||
.linkage = .static,
|
||||
.root_module = exe_mod,
|
||||
});
|
||||
|
||||
if (std.mem.eql(u8, name, "rlgl_standalone")) {
|
||||
//TODO: Make rlgl_standalone example work
|
||||
continue;
|
||||
}
|
||||
if (std.mem.eql(u8, name, "raylib_opengl_interop")) {
|
||||
//TODO: Make raylib_opengl_interop example work
|
||||
continue;
|
||||
}
|
||||
|
||||
const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{ .optimize = optimize });
|
||||
const emcc_settings = emsdk.emccDefaultSettings(b.allocator, .{ .optimize = optimize });
|
||||
|
||||
const install_dir: std.Build.InstallDir = .{ .custom = "htmlout" };
|
||||
const emcc_step = emsdk.emccStep(b, raylib, wasm, .{
|
||||
.optimize = optimize,
|
||||
.flags = emcc_flags,
|
||||
.settings = emcc_settings,
|
||||
.shell_file_path = b.path("src/shell.html"),
|
||||
.embed_paths = &.{
|
||||
.{
|
||||
.src_path = b.pathJoin(&.{ module_subpath, "resources" }),
|
||||
.virtual_path = "resources",
|
||||
},
|
||||
},
|
||||
.install_dir = install_dir,
|
||||
});
|
||||
|
||||
const html_filename = try std.fmt.allocPrint(b.allocator, "{s}.html", .{wasm.name});
|
||||
const emrun_step = emsdk.emrunStep(
|
||||
b,
|
||||
b.getInstallPath(install_dir, html_filename),
|
||||
&.{"--no_browser"},
|
||||
);
|
||||
emrun_step.dependOn(emcc_step);
|
||||
|
||||
run_step.dependOn(emrun_step);
|
||||
all.dependOn(emcc_step);
|
||||
} else {
|
||||
// special examples that test using these external dependencies directly
|
||||
// alongside raylib
|
||||
if (std.mem.eql(u8, name, "rlgl_standalone")) {
|
||||
exe_mod.addIncludePath(b.path("src"));
|
||||
exe_mod.addIncludePath(b.path("src/external/glfw/include"));
|
||||
if (!hasCSource(raylib.root_module, "rglfw.c")) {
|
||||
exe_mod.addCSourceFile(.{ .file = b.path("src/rglfw.c"), .flags = &.{} });
|
||||
}
|
||||
}
|
||||
if (std.mem.eql(u8, name, "raylib_opengl_interop")) {
|
||||
exe_mod.addIncludePath(b.path("src/external"));
|
||||
}
|
||||
|
||||
switch (target.result.os.tag) {
|
||||
.windows => {
|
||||
exe_mod.linkSystemLibrary("winmm", .{});
|
||||
exe_mod.linkSystemLibrary("gdi32", .{});
|
||||
exe_mod.linkSystemLibrary("opengl32", .{});
|
||||
|
||||
exe_mod.addCMacro("PLATFORM_DESKTOP", "");
|
||||
},
|
||||
.linux => {
|
||||
exe_mod.linkSystemLibrary("GL", .{});
|
||||
exe_mod.linkSystemLibrary("rt", .{});
|
||||
exe_mod.linkSystemLibrary("dl", .{});
|
||||
exe_mod.linkSystemLibrary("m", .{});
|
||||
exe_mod.linkSystemLibrary("X11", .{});
|
||||
|
||||
exe_mod.addCMacro("PLATFORM_DESKTOP", "");
|
||||
},
|
||||
.macos => {
|
||||
exe_mod.linkFramework("Foundation", .{});
|
||||
exe_mod.linkFramework("Cocoa", .{});
|
||||
exe_mod.linkFramework("OpenGL", .{});
|
||||
exe_mod.linkFramework("CoreAudio", .{});
|
||||
exe_mod.linkFramework("CoreVideo", .{});
|
||||
exe_mod.linkFramework("IOKit", .{});
|
||||
|
||||
exe_mod.addCMacro("PLATFORM_DESKTOP", "");
|
||||
},
|
||||
else => {
|
||||
@panic("Unsupported OS");
|
||||
},
|
||||
}
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = name,
|
||||
.root_module = exe_mod,
|
||||
});
|
||||
|
||||
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);
|
||||
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
all.dependOn(&install_cmd.step);
|
||||
}
|
||||
}
|
||||
return all;
|
||||
}
|
||||
|
||||
fn waylandGenerate(
|
||||
b: *std.Build,
|
||||
raylib: *std.Build.Step.Compile,
|
||||
|
|
@ -521,196 +665,16 @@ fn waylandGenerate(
|
|||
|
||||
const client_step = b.addSystemCommand(&.{ "wayland-scanner", "client-header" });
|
||||
client_step.addFileArg(b.path(protocolDir));
|
||||
raylib.addIncludePath(client_step.addOutputFileArg(clientHeader).dirname());
|
||||
raylib.root_module.addIncludePath(client_step.addOutputFileArg(clientHeader).dirname());
|
||||
|
||||
const private_step = b.addSystemCommand(&.{ "wayland-scanner", "private-code" });
|
||||
private_step.addFileArg(b.path(protocolDir));
|
||||
raylib.addIncludePath(private_step.addOutputFileArg(privateCode).dirname());
|
||||
raylib.root_module.addIncludePath(private_step.addOutputFileArg(privateCode).dirname());
|
||||
|
||||
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 {
|
||||
const all = b.step(module, "All " ++ module ++ " examples");
|
||||
const module_subpath = b.pathJoin(&.{ "examples", module });
|
||||
const module_resources = b.pathJoin(&.{ module_subpath, "resources@resources" });
|
||||
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;
|
||||
|
||||
if (target.result.os.tag == .emscripten) {
|
||||
const exe_lib = b.addLibrary(.{
|
||||
.name = name,
|
||||
.linkage = .static,
|
||||
.root_module = b.createModule(.{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
}),
|
||||
});
|
||||
exe_lib.addCSourceFile(.{
|
||||
.file = b.path(path),
|
||||
.flags = &.{},
|
||||
});
|
||||
exe_lib.linkLibC();
|
||||
|
||||
if (std.mem.eql(u8, name, "rlgl_standalone")) {
|
||||
//TODO: Make rlgl_standalone example work
|
||||
continue;
|
||||
}
|
||||
if (std.mem.eql(u8, name, "raylib_opengl_interop")) {
|
||||
//TODO: Make raylib_opengl_interop example work
|
||||
continue;
|
||||
}
|
||||
|
||||
exe_lib.linkLibrary(raylib);
|
||||
|
||||
// Include emscripten for cross compilation
|
||||
if (b.lazyDependency("emsdk", .{})) |emsdk_dep| {
|
||||
if (try emSdkSetupStep(b, emsdk_dep)) |emSdkStep| {
|
||||
exe_lib.step.dependOn(&emSdkStep.step);
|
||||
}
|
||||
|
||||
exe_lib.addIncludePath(emsdk_dep.path("upstream/emscripten/cache/sysroot/include"));
|
||||
|
||||
// Create the output directory because emcc can't do it.
|
||||
const emccOutputDirExample = b.pathJoin(&.{ emccOutputDir, name, std.fs.path.sep_str });
|
||||
const mkdir_command = switch (builtin.os.tag) {
|
||||
.windows => b.addSystemCommand(&.{ "cmd.exe", "/c", "if", "not", "exist", emccOutputDirExample, "mkdir", emccOutputDirExample }),
|
||||
else => b.addSystemCommand(&.{ "mkdir", "-p", emccOutputDirExample }),
|
||||
};
|
||||
|
||||
const emcc_exe = switch (builtin.os.tag) {
|
||||
.windows => "emcc.bat",
|
||||
else => "emcc",
|
||||
};
|
||||
|
||||
const emcc_exe_path = b.pathJoin(&.{ emsdk_dep.path("upstream/emscripten").getPath(b), emcc_exe });
|
||||
const emcc_command = b.addSystemCommand(&[_][]const u8{emcc_exe_path});
|
||||
emcc_command.step.dependOn(&mkdir_command.step);
|
||||
const emccOutputDirExampleWithFile = b.pathJoin(&.{ emccOutputDir, name, std.fs.path.sep_str, emccOutputFile });
|
||||
emcc_command.addArgs(&[_][]const u8{
|
||||
"-o",
|
||||
emccOutputDirExampleWithFile,
|
||||
"-sFULL-ES3=1",
|
||||
"-sUSE_GLFW=3",
|
||||
"-sSTACK_OVERFLOW_CHECK=1",
|
||||
"-sEXPORTED_RUNTIME_METHODS=['requestFullscreen']",
|
||||
"-sASYNCIFY",
|
||||
"-O0",
|
||||
"--emrun",
|
||||
"--preload-file",
|
||||
module_resources,
|
||||
"--shell-file",
|
||||
b.path("src/shell.html").getPath(b),
|
||||
});
|
||||
|
||||
const link_items: []const *std.Build.Step.Compile = &.{
|
||||
raylib,
|
||||
exe_lib,
|
||||
};
|
||||
for (link_items) |item| {
|
||||
emcc_command.addFileArg(item.getEmittedBin());
|
||||
emcc_command.step.dependOn(&item.step);
|
||||
}
|
||||
|
||||
const run_step = try emscriptenRunStep(b, emsdk_dep, emccOutputDirExampleWithFile);
|
||||
run_step.step.dependOn(&emcc_command.step);
|
||||
run_step.addArg("--no_browser");
|
||||
const run_option = b.step(name, name);
|
||||
|
||||
run_option.dependOn(&run_step.step);
|
||||
|
||||
all.dependOn(&emcc_command.step);
|
||||
}
|
||||
} else {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = name,
|
||||
.root_module = b.createModule(.{
|
||||
.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) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
.{
|
||||
.name = .raylib,
|
||||
.version = "5.5.0",
|
||||
.version = "5.6.0-dev",
|
||||
.minimum_zig_version = "0.15.1",
|
||||
|
||||
.fingerprint = 0x13035e5cb8bc1ac2, // Changing this has security and trust implications.
|
||||
|
|
@ -14,7 +14,10 @@
|
|||
.emsdk = .{
|
||||
.url = "git+https://github.com/emscripten-core/emsdk#4.0.9",
|
||||
.hash = "N-V-__8AAJl1DwBezhYo_VE6f53mPVm00R-Fk28NPW7P14EQ",
|
||||
.lazy = true,
|
||||
},
|
||||
.zemscripten = .{
|
||||
.url = "git+https://github.com/zig-gamedev/zemscripten#3fa4b778852226c7346bdcc3c1486e875a9a6d02",
|
||||
.hash = "zemscripten-0.2.0-dev-sRlDqApRAACspTbAZnuNKWIzfWzSYgYkb2nWAXZ-tqqt",
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
|||
|
|
@ -30,13 +30,13 @@ void ProcessAudio(void *buffer, unsigned int frames)
|
|||
|
||||
for (unsigned int frame = 0; frame < frames; frame++)
|
||||
{
|
||||
float *left = &samples[frame * 2 + 0], *right = &samples[frame * 2 + 1];
|
||||
float *left = &samples[frame*2 + 0], *right = &samples[frame*2 + 1];
|
||||
|
||||
*left = powf(fabsf(*left), exponent) * ( (*left < 0.0f)? -1.0f : 1.0f );
|
||||
*right = powf(fabsf(*right), exponent) * ( (*right < 0.0f)? -1.0f : 1.0f );
|
||||
*left = powf(fabsf(*left), exponent)*( (*left < 0.0f)? -1.0f : 1.0f );
|
||||
*right = powf(fabsf(*right), exponent)*( (*right < 0.0f)? -1.0f : 1.0f );
|
||||
|
||||
average += fabsf(*left) / frames; // accumulating average volume
|
||||
average += fabsf(*right) / frames;
|
||||
average += fabsf(*left)/frames; // accumulating average volume
|
||||
average += fabsf(*right)/frames;
|
||||
}
|
||||
|
||||
// Moving history to the left
|
||||
|
|
@ -99,7 +99,7 @@ int main(void)
|
|||
DrawRectangle(199, 199, 402, 34, LIGHTGRAY);
|
||||
for (int i = 0; i < 400; i++)
|
||||
{
|
||||
DrawLine(201 + i, 232 - (int)(averageVolume[i] * 32), 201 + i, 232, MAROON);
|
||||
DrawLine(201 + i, 232 - (int)(averageVolume[i]*32), 201 + i, 232, MAROON);
|
||||
}
|
||||
DrawRectangleLines(199, 199, 402, 34, GRAY);
|
||||
|
||||
|
|
|
|||
|
|
@ -115,7 +115,7 @@ int main(void)
|
|||
float fp = (float)(mousePosition.y);
|
||||
frequency = 40.0f + (float)(fp);
|
||||
|
||||
float pan = (float)(mousePosition.x) / (float)screenWidth;
|
||||
float pan = (float)(mousePosition.x)/(float)screenWidth;
|
||||
SetAudioStreamPan(stream, pan);
|
||||
}
|
||||
|
||||
|
|
@ -141,7 +141,7 @@ int main(void)
|
|||
}
|
||||
|
||||
// Scale read cursor's position to minimize transition artifacts
|
||||
//readCursor = (int)(readCursor * ((float)waveLength / (float)oldWavelength));
|
||||
//readCursor = (int)(readCursor*((float)waveLength/(float)oldWavelength));
|
||||
oldFrequency = frequency;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -148,8 +148,8 @@ int main(void)
|
|||
static void AudioProcessEffectLPF(void *buffer, unsigned int frames)
|
||||
{
|
||||
static float low[2] = { 0.0f, 0.0f };
|
||||
static const float cutoff = 70.0f / 44100.0f; // 70 Hz lowpass filter
|
||||
const float k = cutoff / (cutoff + 0.1591549431f); // RC filter formula
|
||||
static const float cutoff = 70.0f/44100.0f; // 70 Hz lowpass filter
|
||||
const float k = cutoff/(cutoff + 0.1591549431f); // RC filter formula
|
||||
|
||||
// Converts the buffer data before using it
|
||||
float *bufferData = (float *)buffer;
|
||||
|
|
@ -158,8 +158,8 @@ static void AudioProcessEffectLPF(void *buffer, unsigned int frames)
|
|||
const float l = bufferData[i];
|
||||
const float r = bufferData[i + 1];
|
||||
|
||||
low[0] += k * (l - low[0]);
|
||||
low[1] += k * (r - low[1]);
|
||||
low[0] += k*(l - low[0]);
|
||||
low[1] += k*(r - low[1]);
|
||||
bufferData[i] = low[0];
|
||||
bufferData[i + 1] = low[1];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -294,7 +294,7 @@ void UpdateCameraPlayerBoundsPush(Camera2D *camera, Player *player, EnvItem *env
|
|||
|
||||
Vector2 bboxWorldMin = GetScreenToWorld2D((Vector2){ (1 - bbox.x)*0.5f*width, (1 - bbox.y)*0.5f*height }, *camera);
|
||||
Vector2 bboxWorldMax = GetScreenToWorld2D((Vector2){ (1 + bbox.x)*0.5f*width, (1 + bbox.y)*0.5f*height }, *camera);
|
||||
camera->offset = (Vector2){ (1 - bbox.x)*0.5f * width, (1 - bbox.y)*0.5f*height };
|
||||
camera->offset = (Vector2){ (1 - bbox.x)*0.5f*width, (1 - bbox.y)*0.5f*height };
|
||||
|
||||
if (player->position.x < bboxWorldMin.x) camera->target.x = player->position.x;
|
||||
if (player->position.y < bboxWorldMin.y) camera->target.y = player->position.y;
|
||||
|
|
|
|||
|
|
@ -100,8 +100,8 @@ int main(void)
|
|||
camera.up = (Vector3){ 0.0f, 1.0f, 0.0f };
|
||||
camera.projection = CAMERA_ORTHOGRAPHIC;
|
||||
camera.fovy = 20.0f; // near plane width in CAMERA_ORTHOGRAPHIC
|
||||
CameraYaw(&camera, -135 * DEG2RAD, true);
|
||||
CameraPitch(&camera, -45 * DEG2RAD, true, true, false);
|
||||
CameraYaw(&camera, -135*DEG2RAD, true);
|
||||
CameraPitch(&camera, -45*DEG2RAD, true, true, false);
|
||||
}
|
||||
else if (camera.projection == CAMERA_ORTHOGRAPHIC)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -263,7 +263,7 @@ static void UpdateCameraAngle(Camera *camera)
|
|||
// Rotate view vector around right axis
|
||||
float pitchAngle = -lookRotation.y -
|
||||
lean.y;
|
||||
pitchAngle = Clamp(pitchAngle, -PI / 2 + 0.0001f, PI / 2 - 0.0001f); // Clamp angle so it doesn't go past straight up or straight down
|
||||
pitchAngle = Clamp(pitchAngle, -PI/2 + 0.0001f, PI/2 - 0.0001f); // Clamp angle so it doesn't go past straight up or straight down
|
||||
Vector3 pitch = Vector3RotateByAxisAngle(yaw, right, pitchAngle);
|
||||
|
||||
// Head animation
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ int main(void)
|
|||
cameraPlayer2.position.x = -3.0f;
|
||||
cameraPlayer2.position.y = 3.0f;
|
||||
|
||||
RenderTexture screenPlayer2 = LoadRenderTexture(screenWidth / 2, screenHeight);
|
||||
RenderTexture screenPlayer2 = LoadRenderTexture(screenWidth/2, screenHeight);
|
||||
|
||||
// Build a flipped rectangle the size of the split view to use for drawing later
|
||||
Rectangle splitScreenRect = { 0.0f, 0.0f, (float)screenPlayer1.texture.width, (float)-screenPlayer1.texture.height };
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ int main(void)
|
|||
|
||||
DrawText("Try clicking on the box with your mouse!", 240, 10, 20, DARKGRAY);
|
||||
|
||||
if (collision.hit) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30)) / 2, (int)(screenHeight * 0.1f), 30, GREEN);
|
||||
if (collision.hit) DrawText("BOX SELECTED", (screenWidth - MeasureText("BOX SELECTED", 30))/2, (int)(screenHeight*0.1f), 30, GREEN);
|
||||
|
||||
DrawText("Right click mouse to toggle camera controls", 10, 430, 10, GRAY);
|
||||
|
||||
|
|
|
|||
|
|
@ -91,7 +91,7 @@ int main(void)
|
|||
int x = (int)(((float)i)/dpiScale.x);
|
||||
if (odd) DrawRectangle(x, pixelGridTop, (int)cellSizePx, pixelGridBottom - pixelGridTop, CLITERAL(Color){ 0, 121, 241, 100 });
|
||||
|
||||
DrawLine(x, pixelGridTop, (int)(((float)i) / dpiScale.x), pixelGridLabelY - 10, GRAY);
|
||||
DrawLine(x, pixelGridTop, (int)(((float)i)/dpiScale.x), pixelGridLabelY - 10, GRAY);
|
||||
|
||||
if ((x - lastTextX) >= minTextSpace)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -175,7 +175,6 @@ static void DrawTextCenterKeyHelp(const char *key, const char *text, int posX, i
|
|||
int spaceSize = MeasureText(" ", fontSize);
|
||||
int pressSize = MeasureText("Press", fontSize);
|
||||
int keySize = MeasureText(key, fontSize);
|
||||
int textSize = MeasureText(text, fontSize);
|
||||
int textSizeCurrent = 0;
|
||||
|
||||
DrawText("Press", posX, posY, fontSize, color);
|
||||
|
|
@ -184,4 +183,4 @@ static void DrawTextCenterKeyHelp(const char *key, const char *text, int posX, i
|
|||
DrawRectangle(posX + textSizeCurrent, posY + fontSize, keySize, 3, RED);
|
||||
textSizeCurrent += keySize + 2*spaceSize;
|
||||
DrawText(text, posX + textSizeCurrent, posY, fontSize, color);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ int main(void)
|
|||
//SetConfigFlags(FLAG_VSYNC_HINT | FLAG_MSAA_4X_HINT | FLAG_WINDOW_HIGHDPI);
|
||||
InitWindow(screenWidth, screenHeight, "raylib [core] example - window flags");
|
||||
|
||||
Vector2 ballPosition = { GetScreenWidth() / 2.0f, GetScreenHeight() / 2.0f };
|
||||
Vector2 ballPosition = { GetScreenWidth()/2.0f, GetScreenHeight()/2.0f };
|
||||
Vector2 ballSpeed = { 5.0f, 4.0f };
|
||||
float ballRadius = 20;
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ int main(void)
|
|||
|
||||
EndMode3D();
|
||||
|
||||
DrawText("Enemy: 100 / 100", (int)cubeScreenPosition.x - MeasureText("Enemy: 100/100", 20)/2, (int)cubeScreenPosition.y, 20, BLACK);
|
||||
DrawText("Enemy: 100/100", (int)cubeScreenPosition.x - MeasureText("Enemy: 100/100", 20)/2, (int)cubeScreenPosition.y, 20, BLACK);
|
||||
|
||||
DrawText(TextFormat("Cube position in screen space coordinates: [%i, %i]", (int)cubeScreenPosition.x, (int)cubeScreenPosition.y), 10, 10, 20, LIME);
|
||||
DrawText("Text 2d should be always on top of the cube", 10, 40, 20, GRAY);
|
||||
|
|
@ -84,4 +84,4 @@ int main(void)
|
|||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -127,8 +127,8 @@ int main(void)
|
|||
if (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE))
|
||||
{
|
||||
const Vector2 mouseDelta = GetMouseDelta();
|
||||
camerarot.x = mouseDelta.x * 0.05f;
|
||||
camerarot.y = mouseDelta.y * 0.05f;
|
||||
camerarot.x = mouseDelta.x*0.05f;
|
||||
camerarot.y = mouseDelta.y*0.05f;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -138,14 +138,14 @@ int main(void)
|
|||
|
||||
UpdateCameraPro(&camera,
|
||||
(Vector3) {
|
||||
(IsKeyDown(KEY_W) || IsKeyDown(KEY_UP)) * 0.1f - // Move forward-backward
|
||||
(IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN)) * 0.1f,
|
||||
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT)) * 0.1f - // Move right-left
|
||||
(IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT)) * 0.1f,
|
||||
(IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward
|
||||
(IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f,
|
||||
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left
|
||||
(IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f,
|
||||
0.0f // Move up-down
|
||||
},
|
||||
camerarot,
|
||||
GetMouseWheelMove() * -2.0f); // Move to target (zoom)
|
||||
GetMouseWheelMove()*-2.0f); // Move to target (zoom)
|
||||
|
||||
// Cycle between models on mouse click
|
||||
if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) currentModel = (currentModel + 1) % MAX_VOX_FILES;
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include "raylib.h"
|
||||
#include "raymath.h"
|
||||
|
||||
#undef FLT_MAX
|
||||
#define FLT_MAX 340282346638528859811704183484516925440.0f // Maximum value of a float, from bit pattern 01111111011111111111111111111111
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
|
|
@ -245,4 +246,4 @@ int main(void)
|
|||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -161,9 +161,9 @@ static Mesh GenMeshPoints(int numPoints)
|
|||
// https://en.wikipedia.org/wiki/Spherical_coordinate_system
|
||||
for (int i = 0; i < numPoints; i++)
|
||||
{
|
||||
float theta = ((float)PI*rand())/RAND_MAX;
|
||||
float phi = (2.0f*PI*rand())/RAND_MAX;
|
||||
float r = (10.0f*rand())/RAND_MAX;
|
||||
float theta = ((float)PI*rand())/((float)RAND_MAX);
|
||||
float phi = (2.0f*PI*rand())/((float)RAND_MAX);
|
||||
float r = (10.0f*rand())/((float)RAND_MAX);
|
||||
|
||||
mesh.vertices[i*3 + 0] = r*sinf(theta)*cosf(phi);
|
||||
mesh.vertices[i*3 + 1] = r*sinf(theta)*sinf(phi);
|
||||
|
|
|
|||
|
|
@ -79,9 +79,9 @@ int main(void)
|
|||
// Projection from XYZW to XYZ from perspective point (0, 0, 0, 3)
|
||||
// NOTE: Trace a ray from (0, 0, 0, 3) > p and continue until W = 0
|
||||
float c = 3.0f/(3.0f - p.w);
|
||||
p.x = c * p.x;
|
||||
p.y = c * p.y;
|
||||
p.z = c * p.z;
|
||||
p.x = c*p.x;
|
||||
p.y = c*p.y;
|
||||
p.z = c*p.z;
|
||||
|
||||
// Split XYZ coordinate and W values later for drawing
|
||||
transformed[i] = (Vector3){ p.x, p.y, p.z };
|
||||
|
|
@ -125,4 +125,4 @@ int main(void)
|
|||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ void main()
|
|||
light = normalize(lights[i].position - fragPosition);
|
||||
|
||||
float NdotL = max(dot(normal, light), 0.0);
|
||||
lightDot += lights[i].color.rgb * NdotL;
|
||||
lightDot += lights[i].color.rgb*NdotL;
|
||||
|
||||
if (NdotL > 0.0)
|
||||
{
|
||||
|
|
@ -56,8 +56,8 @@ void main()
|
|||
}
|
||||
}
|
||||
|
||||
vec4 finalColor = (fragColor * ((colDiffuse + vec4(specular, 1.0)) * vec4(lightDot, 1.0)));
|
||||
finalColor += fragColor * (ambient / 10.0) * colDiffuse;
|
||||
vec4 finalColor = (fragColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
|
||||
finalColor += fragColor*(ambient/10.0)*colDiffuse;
|
||||
|
||||
finalColor = pow(finalColor, vec4(1.0/2.2)); // gamma correction
|
||||
|
||||
|
|
|
|||
|
|
@ -20,9 +20,9 @@ varying vec3 fragNormal;
|
|||
|
||||
void main()
|
||||
{
|
||||
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
|
||||
fragColor = vertexColor;
|
||||
fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 1.0)));
|
||||
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
|
||||
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ void main()
|
|||
light = normalize(lights[i].position - fragPosition);
|
||||
|
||||
float NdotL = max(dot(normal, light), 0.0);
|
||||
lightDot += lights[i].color.rgb * NdotL;
|
||||
lightDot += lights[i].color.rgb*NdotL;
|
||||
|
||||
if (NdotL > 0.0)
|
||||
{
|
||||
|
|
@ -53,8 +53,8 @@ void main()
|
|||
}
|
||||
}
|
||||
|
||||
vec4 finalColor = (fragColor * ((colDiffuse + vec4(specular, 1.0)) * vec4(lightDot, 1.0)));
|
||||
finalColor += fragColor * (ambient / 10.0) * colDiffuse;
|
||||
vec4 finalColor = (fragColor*((colDiffuse + vec4(specular, 1.0))*vec4(lightDot, 1.0)));
|
||||
finalColor += fragColor*(ambient/10.0)*colDiffuse;
|
||||
|
||||
finalColor = pow(finalColor, vec4(1.0/2.2)); // gamma correction
|
||||
|
||||
|
|
|
|||
|
|
@ -16,9 +16,9 @@ varying vec3 fragNormal;
|
|||
|
||||
void main()
|
||||
{
|
||||
fragPosition = vec3(matModel * vec4(vertexPosition, 1.0));
|
||||
fragPosition = vec3(matModel*vec4(vertexPosition, 1.0));
|
||||
fragColor = vertexColor;
|
||||
fragNormal = normalize(vec3(matNormal * vec4(vertexNormal, 1.0)));
|
||||
fragNormal = normalize(vec3(matNormal*vec4(vertexNormal, 1.0)));
|
||||
|
||||
gl_Position = mvp * vec4(vertexPosition, 1.0);
|
||||
gl_Position = mvp*vec4(vertexPosition, 1.0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -297,7 +297,7 @@ static void DrawRectangleV(Vector2 position, Vector2 size, Color color)
|
|||
// Draw a grid centered at (0, 0, 0)
|
||||
static void DrawGrid(int slices, float spacing)
|
||||
{
|
||||
int halfSlices = slices / 2;
|
||||
int halfSlices = slices/2;
|
||||
|
||||
rlBegin(RL_LINES);
|
||||
for (int i = -halfSlices; i <= halfSlices; i++)
|
||||
|
|
|
|||
|
|
@ -1,22 +1,22 @@
|
|||
/*******************************************************************************************
|
||||
*
|
||||
* raylib [shaders] example - normal map
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
|
||||
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
*
|
||||
* Example contributed by Jeremy Montgomery (@Sir_Irk) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2025-2025 Jeremy Montgomery (@Sir_Irk) and Ramon Santamaria (@raysan5)
|
||||
*k
|
||||
********************************************************************************************/
|
||||
*
|
||||
* raylib [shaders] example - normal map
|
||||
*
|
||||
* Example complexity rating: [★★★★] 4/4
|
||||
*
|
||||
* NOTE: This example requires raylib OpenGL 3.3 or ES2 versions for shaders support,
|
||||
* OpenGL 1.1 does not support shaders, recompile raylib to OpenGL 3.3 version
|
||||
*
|
||||
* Example originally created with raylib 5.6, last time updated with raylib 5.6
|
||||
*
|
||||
* Example contributed by Jeremy Montgomery (@Sir_Irk) and reviewed by Ramon Santamaria (@raysan5)
|
||||
*
|
||||
* Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
* BSD-like license that allows static linking with closed source software
|
||||
*
|
||||
* Copyright (c) 2025-2025 Jeremy Montgomery (@Sir_Irk) and Ramon Santamaria (@raysan5)
|
||||
*
|
||||
********************************************************************************************/
|
||||
|
||||
#include <raylib.h>
|
||||
|
||||
|
|
|
|||
|
|
@ -115,22 +115,22 @@ int main(void)
|
|||
if (IsKeyDown(KEY_LEFT))
|
||||
{
|
||||
if (lightDir.x < 0.6f)
|
||||
lightDir.x += cameraSpeed * 60.0f * dt;
|
||||
lightDir.x += cameraSpeed*60.0f*dt;
|
||||
}
|
||||
if (IsKeyDown(KEY_RIGHT))
|
||||
{
|
||||
if (lightDir.x > -0.6f)
|
||||
lightDir.x -= cameraSpeed * 60.0f * dt;
|
||||
lightDir.x -= cameraSpeed*60.0f*dt;
|
||||
}
|
||||
if (IsKeyDown(KEY_UP))
|
||||
{
|
||||
if (lightDir.z < 0.6f)
|
||||
lightDir.z += cameraSpeed * 60.0f * dt;
|
||||
lightDir.z += cameraSpeed*60.0f*dt;
|
||||
}
|
||||
if (IsKeyDown(KEY_DOWN))
|
||||
{
|
||||
if (lightDir.z > -0.6f)
|
||||
lightDir.z -= cameraSpeed * 60.0f * dt;
|
||||
lightDir.z -= cameraSpeed*60.0f*dt;
|
||||
}
|
||||
lightDir = Vector3Normalize(lightDir);
|
||||
lightCam.position = Vector3Scale(lightDir, -15.0f);
|
||||
|
|
|
|||
|
|
@ -130,12 +130,12 @@ int main(void)
|
|||
|
||||
while ((fabs(spots[i].speed.x) + fabs(spots[i].speed.y)) < 2)
|
||||
{
|
||||
spots[i].speed.x = GetRandomValue(-400, 40) / 10.0f;
|
||||
spots[i].speed.y = GetRandomValue(-400, 40) / 10.0f;
|
||||
spots[i].speed.x = GetRandomValue(-400, 40)/10.0f;
|
||||
spots[i].speed.y = GetRandomValue(-400, 40)/10.0f;
|
||||
}
|
||||
|
||||
spots[i].inner = 28.0f * (i + 1);
|
||||
spots[i].radius = 48.0f * (i + 1);
|
||||
spots[i].inner = 28.0f*(i + 1);
|
||||
spots[i].radius = 48.0f*(i + 1);
|
||||
|
||||
SetShaderValue(shdrSpot, spots[i].positionLoc, &spots[i].position.x, SHADER_UNIFORM_VEC2);
|
||||
SetShaderValue(shdrSpot, spots[i].innerLoc, &spots[i].inner, SHADER_UNIFORM_FLOAT);
|
||||
|
|
|
|||
|
|
@ -133,7 +133,7 @@ int main(void)
|
|||
static void UpdateClock(Clock *clock)
|
||||
{
|
||||
time_t rawtime;
|
||||
struct tm * timeinfo;
|
||||
struct tm *timeinfo;
|
||||
|
||||
time(&rawtime);
|
||||
timeinfo = localtime(&rawtime);
|
||||
|
|
@ -164,7 +164,7 @@ static void DrawClock(Clock clock, Vector2 centerPosition)
|
|||
|
||||
DrawText(TextFormat("%i", clock.second.value), centerPosition.x + (clock.second.length - 10)*cosf(clock.second.angle*(float)(PI/180)) - DIGIT_SIZE/2, centerPosition.y + clock.second.length*sinf(clock.second.angle*(float)(PI/180)) - DIGIT_SIZE/2, DIGIT_SIZE, GRAY);
|
||||
|
||||
DrawText(TextFormat("%i", clock.minute.value), clock.minute.origin.x + clock.minute.length*cosf(clock.minute.angle*(float)(PI/180)) - DIGIT_SIZE/2, centerPosition.y + clock.minute.length*sinf(clock.minute.angle*(float)(PI/180)) - DIGIT_SIZE/2, DIGIT_SIZE, RED);
|
||||
DrawText(TextFormat("%i", clock.minute.value), centerPosition.x + clock.minute.length*cosf(clock.minute.angle*(float)(PI/180)) - DIGIT_SIZE/2, centerPosition.y + clock.minute.length*sinf(clock.minute.angle*(float)(PI/180)) - DIGIT_SIZE/2, DIGIT_SIZE, RED);
|
||||
|
||||
DrawText(TextFormat("%i", clock.hour.value), centerPosition.x + clock.hour.length*cosf(clock.hour.angle*(float)(PI/180)) - DIGIT_SIZE/2, centerPosition.y + clock.hour.length*sinf(clock.hour.angle*(float)(PI/180)) - DIGIT_SIZE/2, DIGIT_SIZE, GOLD);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ int main(void)
|
|||
InitWindow(screenWidth, screenHeight, "raylib [shapes] example - double pendulum");
|
||||
|
||||
// Simulation Paramters
|
||||
float l1 = 15, m1 = 0.2, theta1 = DEG2RAD * 170, w1 = 0;
|
||||
float l2 = 15, m2 = 0.1, theta2 = DEG2RAD * 0, w2 = 0;
|
||||
float l1 = 15, m1 = 0.2, theta1 = DEG2RAD*170, w1 = 0;
|
||||
float l2 = 15, m2 = 0.1, theta2 = DEG2RAD*0, w2 = 0;
|
||||
float lengthScaler = 0.1;
|
||||
float totalM = m1 + m2;
|
||||
|
||||
|
|
@ -56,8 +56,8 @@ int main(void)
|
|||
previousPosition.y += (screenHeight/2 - 100);
|
||||
|
||||
// Scale length
|
||||
float L1 = l1 * lengthScaler;
|
||||
float L2 = l2 * lengthScaler;
|
||||
float L1 = l1*lengthScaler;
|
||||
float L2 = l2*lengthScaler;
|
||||
|
||||
// Draw parameters
|
||||
int lineThick = 20, trailThick = 2;
|
||||
|
|
@ -76,26 +76,26 @@ int main(void)
|
|||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
float dt = GetFrameTime();
|
||||
float step = dt / SIMULATION_STEPS, step2 = step * step;
|
||||
float step = dt/SIMULATION_STEPS, step2 = step*step;
|
||||
|
||||
// Update Physics - larger steps = better approximation
|
||||
for (int i = 0; i < SIMULATION_STEPS; ++i)
|
||||
{
|
||||
float delta = theta1 - theta2;
|
||||
float sinD = sinf(delta), cosD = cosf(delta), cos2D = cosf(2*delta);
|
||||
float ww1 = w1 * w1, ww2 = w2 * w2;
|
||||
float ww1 = w1*w1, ww2 = w2*w2;
|
||||
|
||||
// Calculate a1
|
||||
float a1 = (-G*(2*m1 + m2)*sinf(theta1)
|
||||
- m2*G*sinf(theta1 - 2*theta2)
|
||||
- 2*sinD*m2*(ww2*L2 + ww1*L1*cosD))
|
||||
/ (L1*(2*m1 + m2 - m2*cos2D));
|
||||
/(L1*(2*m1 + m2 - m2*cos2D));
|
||||
|
||||
// Calculate a2
|
||||
float a2 = (2*sinD*(ww1*L1*totalM
|
||||
+ G*totalM*cosf(theta1)
|
||||
+ ww2*L2*m2*cosD))
|
||||
/ (L2*(2*m1 + m2 - m2*cos2D));
|
||||
/(L2*(2*m1 + m2 - m2*cos2D));
|
||||
|
||||
// Update thetas
|
||||
theta1 += w1*step + 0.5f*a1*step2;
|
||||
|
|
@ -118,7 +118,7 @@ int main(void)
|
|||
|
||||
// Draw trail
|
||||
DrawCircleV(previousPosition, trailThick, RED);
|
||||
DrawLineEx(previousPosition, currentPosition, trailThick * 2, RED);
|
||||
DrawLineEx(previousPosition, currentPosition, trailThick*2, RED);
|
||||
EndTextureMode();
|
||||
|
||||
// Update previous position
|
||||
|
|
@ -135,12 +135,12 @@ int main(void)
|
|||
DrawTextureRec(target.texture, (Rectangle){ 0, 0, target.texture.width, -target.texture.height }, (Vector2){ 0, 0 }, WHITE);
|
||||
|
||||
// Draw double pendulum
|
||||
DrawRectanglePro((Rectangle){ screenWidth/2, screenHeight/2 - 100, 10 * l1, lineThick },
|
||||
(Vector2){0, lineThick * 0.5}, 90 - RAD2DEG * theta1, RAYWHITE);
|
||||
DrawRectanglePro((Rectangle){ screenWidth/2, screenHeight/2 - 100, 10*l1, lineThick },
|
||||
(Vector2){0, lineThick*0.5}, 90 - RAD2DEG*theta1, RAYWHITE);
|
||||
|
||||
Vector2 endpoint1 = CalculatePendulumEndPoint(l1, theta1);
|
||||
DrawRectanglePro((Rectangle){ screenWidth/2 + endpoint1.x, screenHeight/2 - 100 + endpoint1.y, 10 * l2, lineThick },
|
||||
(Vector2){0, lineThick * 0.5}, 90 - RAD2DEG * theta2, RAYWHITE);
|
||||
DrawRectanglePro((Rectangle){ screenWidth/2 + endpoint1.x, screenHeight/2 - 100 + endpoint1.y, 10*l2, lineThick },
|
||||
(Vector2){0, lineThick*0.5}, 90 - RAD2DEG*theta2, RAYWHITE);
|
||||
|
||||
EndDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
|
@ -159,7 +159,7 @@ int main(void)
|
|||
// Calculate Pendulum End Point
|
||||
static Vector2 CalculatePendulumEndPoint(float l, float theta)
|
||||
{
|
||||
return (Vector2){ 10 * l * sin(theta), 10 * l * cos(theta) };
|
||||
return (Vector2){ 10*l*sin(theta), 10*l*cos(theta) };
|
||||
}
|
||||
|
||||
// Calculate Double Pendulum End Point
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ int main(void)
|
|||
GuiSliderBar((Rectangle){ 600, 170, 120, 20}, "Segments", TextFormat("%.2f", segments), &segments, 0, 100);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
minSegments = truncf(ceilf((endAngle - startAngle) / 90));
|
||||
minSegments = truncf(ceilf((endAngle - startAngle)/90));
|
||||
DrawText(TextFormat("MODE: %s", (segments >= minSegments)? "MANUAL" : "AUTO"), 600, 200, 10, (segments >= minSegments)? MAROON : DARKGRAY);
|
||||
|
||||
DrawFPS(10, 10);
|
||||
|
|
@ -87,4 +87,4 @@ int main(void)
|
|||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ int main(void)
|
|||
//----------------------------------------------------------------------------------
|
||||
float width = GetScreenWidth()/2.0f, height = GetScreenHeight()/6.0f;
|
||||
Rectangle rec = {
|
||||
GetScreenWidth() / 2.0f - width/2,
|
||||
GetScreenHeight() / 2.0f - 5*(height/2),
|
||||
GetScreenWidth()/2.0f - width/2,
|
||||
GetScreenHeight()/2.0f - 5*(height/2),
|
||||
width, height
|
||||
};
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -129,8 +129,8 @@ void SetupLight(int slot, float x, float y, float radius)
|
|||
lights[slot].mask = LoadRenderTexture(GetScreenWidth(), GetScreenHeight());
|
||||
lights[slot].outerRadius = radius;
|
||||
|
||||
lights[slot].bounds.width = radius * 2;
|
||||
lights[slot].bounds.height = radius * 2;
|
||||
lights[slot].bounds.width = radius*2;
|
||||
lights[slot].bounds.height = radius*2;
|
||||
|
||||
MoveLight(slot, x, y);
|
||||
|
||||
|
|
@ -355,4 +355,4 @@ int main(void)
|
|||
//--------------------------------------------------------------------------------------
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -248,7 +248,7 @@ int main(void)
|
|||
if (sz.x > 300) { sz.y *= sz.x/300; sz.x = 300; }
|
||||
else if (sz.x < 160) sz.x = 160;
|
||||
|
||||
Rectangle msgRect = { selectedPos.x - 38.8f, selectedPos.y, 2 * horizontalPadding + sz.x, 2 * verticalPadding + sz.y };
|
||||
Rectangle msgRect = { selectedPos.x - 38.8f, selectedPos.y, 2*horizontalPadding + sz.x, 2*verticalPadding + sz.y };
|
||||
msgRect.y -= msgRect.height;
|
||||
|
||||
// Coordinates for the chat bubble triangle
|
||||
|
|
|
|||
|
|
@ -78,10 +78,10 @@ int main(void)
|
|||
|
||||
switch (blendMode)
|
||||
{
|
||||
case BLEND_ALPHA: DrawText("Current: BLEND_ALPHA", (screenWidth / 2) - 60, 370, 10, GRAY); break;
|
||||
case BLEND_ADDITIVE: DrawText("Current: BLEND_ADDITIVE", (screenWidth / 2) - 60, 370, 10, GRAY); break;
|
||||
case BLEND_MULTIPLIED: DrawText("Current: BLEND_MULTIPLIED", (screenWidth / 2) - 60, 370, 10, GRAY); break;
|
||||
case BLEND_ADD_COLORS: DrawText("Current: BLEND_ADD_COLORS", (screenWidth / 2) - 60, 370, 10, GRAY); break;
|
||||
case BLEND_ALPHA: DrawText("Current: BLEND_ALPHA", (screenWidth/2) - 60, 370, 10, GRAY); break;
|
||||
case BLEND_ADDITIVE: DrawText("Current: BLEND_ADDITIVE", (screenWidth/2) - 60, 370, 10, GRAY); break;
|
||||
case BLEND_MULTIPLIED: DrawText("Current: BLEND_MULTIPLIED", (screenWidth/2) - 60, 370, 10, GRAY); break;
|
||||
case BLEND_ADD_COLORS: DrawText("Current: BLEND_ADD_COLORS", (screenWidth/2) - 60, 370, 10, GRAY); break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -64,10 +64,10 @@ int main(void)
|
|||
Rectangle fudesumiRec = {0, 0, fudesumiImage.width, fudesumiImage.height};
|
||||
|
||||
Rectangle fudesumiPos = {50, 10, fudesumiImage.width*0.8f, fudesumiImage.height*0.8f};
|
||||
Rectangle redPos = { 410, 10, fudesumiPos.width / 2, fudesumiPos.height / 2 };
|
||||
Rectangle greenPos = { 600, 10, fudesumiPos.width / 2, fudesumiPos.height / 2 };
|
||||
Rectangle bluePos = { 410, 230, fudesumiPos.width / 2, fudesumiPos.height / 2 };
|
||||
Rectangle alphaPos = { 600, 230, fudesumiPos.width / 2, fudesumiPos.height / 2 };
|
||||
Rectangle redPos = { 410, 10, fudesumiPos.width/2, fudesumiPos.height/2 };
|
||||
Rectangle greenPos = { 600, 10, fudesumiPos.width/2, fudesumiPos.height/2 };
|
||||
Rectangle bluePos = { 410, 230, fudesumiPos.width/2, fudesumiPos.height/2 };
|
||||
Rectangle alphaPos = { 600, 230, fudesumiPos.width/2, fudesumiPos.height/2 };
|
||||
|
||||
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -18,8 +18,8 @@ int main() {
|
|||
SetTargetFPS(60);
|
||||
|
||||
while (!WindowShouldClose()) {
|
||||
cam.position.x = sin(GetTime()) * 10.0f;
|
||||
cam.position.z = cos(GetTime()) * 10.0f;
|
||||
cam.position.x = sin(GetTime())*10.0f;
|
||||
cam.position.z = cos(GetTime())*10.0f;
|
||||
|
||||
BeginDrawing();
|
||||
ClearBackground(RAYWHITE);
|
||||
|
|
@ -35,4 +35,4 @@ int main() {
|
|||
|
||||
CloseWindow();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
2
src/external/fix_win32_compatibility.h
vendored
2
src/external/fix_win32_compatibility.h
vendored
|
|
@ -42,7 +42,7 @@
|
|||
#define DrawTextW DrawTextWin32
|
||||
#define DrawTextExA DrawTextExAWin32
|
||||
#define DrawTextExW DrawTextExWin32
|
||||
#define PlaySoundA PlaySoundAWin32\
|
||||
#define PlaySoundA PlaySoundAWin32
|
||||
// include windows
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#include <windows.h>
|
||||
|
|
|
|||
14
src/external/rl_gputex.h
vendored
14
src/external/rl_gputex.h
vendored
|
|
@ -288,7 +288,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
|||
if (header->ddspf.flags == 0x40) // No alpha channel
|
||||
{
|
||||
int data_size = image_pixel_size*sizeof(unsigned short);
|
||||
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
|
||||
if (header->mipmap_count > 1) data_size = data_size + data_size/3;
|
||||
image_data = RL_GPUTEX_MALLOC(data_size);
|
||||
|
||||
RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
|
||||
|
|
@ -300,7 +300,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
|||
if (header->ddspf.a_bit_mask == 0x8000) // 1bit alpha
|
||||
{
|
||||
int data_size = image_pixel_size*sizeof(unsigned short);
|
||||
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
|
||||
if (header->mipmap_count > 1) data_size = data_size + data_size/3;
|
||||
image_data = RL_GPUTEX_MALLOC(data_size);
|
||||
|
||||
RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
|
||||
|
|
@ -320,7 +320,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
|||
else if (header->ddspf.a_bit_mask == 0xf000) // 4bit alpha
|
||||
{
|
||||
int data_size = image_pixel_size*sizeof(unsigned short);
|
||||
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
|
||||
if (header->mipmap_count > 1) data_size = data_size + data_size/3;
|
||||
image_data = RL_GPUTEX_MALLOC(data_size);
|
||||
|
||||
RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
|
||||
|
|
@ -342,7 +342,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
|||
else if ((header->ddspf.flags == 0x40) && (header->ddspf.rgb_bit_count == 24)) // DDS_RGB, no compressed
|
||||
{
|
||||
int data_size = image_pixel_size*3*sizeof(unsigned char);
|
||||
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
|
||||
if (header->mipmap_count > 1) data_size = data_size + data_size/3;
|
||||
image_data = RL_GPUTEX_MALLOC(data_size);
|
||||
|
||||
RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
|
||||
|
|
@ -352,7 +352,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
|||
else if ((header->ddspf.flags == 0x41) && (header->ddspf.rgb_bit_count == 32)) // DDS_RGBA, no compressed
|
||||
{
|
||||
int data_size = image_pixel_size*4*sizeof(unsigned char);
|
||||
if (header->mipmap_count > 1) data_size = data_size + data_size / 3;
|
||||
if (header->mipmap_count > 1) data_size = data_size + data_size/3;
|
||||
image_data = RL_GPUTEX_MALLOC(data_size);
|
||||
|
||||
RL_GPUTEX_MEMCPY(image_data, file_data_ptr, data_size);
|
||||
|
|
@ -376,7 +376,7 @@ void *rl_load_dds_from_memory(const unsigned char *file_data, unsigned int file_
|
|||
int data_size = 0;
|
||||
|
||||
// Calculate data size, including all mipmaps
|
||||
if (header->mipmap_count > 1) data_size = header->pitch_or_linear_size + header->pitch_or_linear_size / 3;
|
||||
if (header->mipmap_count > 1) data_size = header->pitch_or_linear_size + header->pitch_or_linear_size/3;
|
||||
else data_size = header->pitch_or_linear_size;
|
||||
|
||||
image_data = RL_GPUTEX_MALLOC(data_size*sizeof(unsigned char));
|
||||
|
|
@ -1547,4 +1547,4 @@ typedef enum VkFormat {
|
|||
// Provided by VK_KHR_maintenance5
|
||||
VK_FORMAT_A8_UNORM_KHR = VK_FORMAT_A8_UNORM,
|
||||
} VkFormat;
|
||||
*/
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
* Custom flag for rcore on target platform -not used-
|
||||
*
|
||||
* DEPENDENCIES:
|
||||
* - rglfw: Manage graphic device, OpenGL context and inputs (Windows, Linux, OSX, FreeBSD...)
|
||||
* - rglfw: Manage graphic device, OpenGL context and inputs (Windows, Linux, OSX/macOS, FreeBSD...)
|
||||
* - gestures: Gestures system for touch-ready devices (or simulated from mouse inputs)
|
||||
*
|
||||
*
|
||||
|
|
|
|||
|
|
@ -1041,8 +1041,8 @@ void PollInputEvents(void)
|
|||
// if we are doing automatic DPI scaling, then the "screen" size is divided by the window scale
|
||||
if (IsWindowState(FLAG_WINDOW_HIGHDPI))
|
||||
{
|
||||
CORE.Window.screen.width = (int)(platform.window->r.w / GetWindowScaleDPI().x);
|
||||
CORE.Window.screen.height = (int)(platform.window->r.h / GetWindowScaleDPI().y);
|
||||
CORE.Window.screen.width = (int)(platform.window->r.w/GetWindowScaleDPI().x);
|
||||
CORE.Window.screen.height = (int)(platform.window->r.h/GetWindowScaleDPI().y);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1207,13 +1207,13 @@ void PollInputEvents(void)
|
|||
{
|
||||
case 0:
|
||||
{
|
||||
CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_LEFT_X] = event->axis[0].x / 100.0f;
|
||||
CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_LEFT_Y] = event->axis[0].y / 100.0f;
|
||||
CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_LEFT_X] = event->axis[0].x/100.0f;
|
||||
CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_LEFT_Y] = event->axis[0].y/100.0f;
|
||||
} break;
|
||||
case 1:
|
||||
{
|
||||
CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_RIGHT_X] = event->axis[1].x / 100.0f;
|
||||
CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_RIGHT_Y] = event->axis[1].y / 100.0f;
|
||||
CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_RIGHT_X] = event->axis[1].x/100.0f;
|
||||
CORE.Input.Gamepad.axisState[event->gamepad][GAMEPAD_AXIS_RIGHT_Y] = event->axis[1].y/100.0f;
|
||||
} break;
|
||||
case 2: axis = GAMEPAD_AXIS_LEFT_TRIGGER;
|
||||
case 3:
|
||||
|
|
|
|||
|
|
@ -1485,8 +1485,8 @@ void PollInputEvents(void)
|
|||
// if we are doing automatic DPI scaling, then the "screen" size is divided by the window scale
|
||||
if (IsWindowState(FLAG_WINDOW_HIGHDPI))
|
||||
{
|
||||
CORE.Window.screen.width = (int)(width / GetWindowScaleDPI().x);
|
||||
CORE.Window.screen.height = (int)(height / GetWindowScaleDPI().y);
|
||||
CORE.Window.screen.width = (int)(width/GetWindowScaleDPI().x);
|
||||
CORE.Window.screen.height = (int)(height/GetWindowScaleDPI().y);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -53,6 +53,7 @@
|
|||
#include <termios.h> // POSIX terminal control definitions - tcgetattr(), tcsetattr()
|
||||
#include <pthread.h> // POSIX threads management (inputs reading)
|
||||
#include <dirent.h> // POSIX directory browsing
|
||||
#include <limits.h> // INT_MAX
|
||||
|
||||
#include <sys/ioctl.h> // Required for: ioctl() - UNIX System call for device-specific input/output operations
|
||||
#include <linux/kd.h> // Linux: KDSKBMODE, K_MEDIUMRAM constants definition
|
||||
|
|
@ -2150,6 +2151,8 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
|||
if (NULL == connector) return -1;
|
||||
|
||||
int nearestIndex = -1;
|
||||
int minUnusedPixels = INT_MAX;
|
||||
int minFpsDiff = INT_MAX;
|
||||
for (int i = 0; i < platform.connector->count_modes; i++)
|
||||
{
|
||||
const drmModeModeInfo *const mode = &platform.connector->modes[i];
|
||||
|
|
@ -2169,21 +2172,17 @@ static int FindNearestConnectorMode(const drmModeConnector *connector, uint widt
|
|||
continue;
|
||||
}
|
||||
|
||||
if (nearestIndex < 0)
|
||||
const int unusedPixels = (mode->hdisplay - width) * (mode->vdisplay - height);
|
||||
const int fpsDiff = mode->vrefresh - fps;
|
||||
|
||||
if ((unusedPixels < minUnusedPixels) ||
|
||||
((unusedPixels == minUnusedPixels) && (abs(fpsDiff) < abs(minFpsDiff))) ||
|
||||
((unusedPixels == minUnusedPixels) && (abs(fpsDiff) == abs(minFpsDiff)) && (fpsDiff > 0)))
|
||||
{
|
||||
nearestIndex = i;
|
||||
continue;
|
||||
minUnusedPixels = unusedPixels;
|
||||
minFpsDiff = fpsDiff;
|
||||
}
|
||||
|
||||
const int widthDiff = abs(mode->hdisplay - width);
|
||||
const int heightDiff = abs(mode->vdisplay - height);
|
||||
const int fpsDiff = abs(mode->vrefresh - fps);
|
||||
|
||||
const int nearestWidthDiff = abs(platform.connector->modes[nearestIndex].hdisplay - width);
|
||||
const int nearestHeightDiff = abs(platform.connector->modes[nearestIndex].vdisplay - height);
|
||||
const int nearestFpsDiff = abs(platform.connector->modes[nearestIndex].vrefresh - fps);
|
||||
|
||||
if ((widthDiff < nearestWidthDiff) || (heightDiff < nearestHeightDiff) || (fpsDiff < nearestFpsDiff)) nearestIndex = i;
|
||||
}
|
||||
|
||||
return nearestIndex;
|
||||
|
|
|
|||
|
|
@ -1466,11 +1466,11 @@ RLAPI int GetPixelDataSize(int width, int height, int format); // G
|
|||
// Font loading/unloading functions
|
||||
RLAPI Font GetFontDefault(void); // Get the default Font
|
||||
RLAPI Font LoadFont(const char *fileName); // Load font from file into GPU memory (VRAM)
|
||||
RLAPI Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
|
||||
RLAPI Font LoadFontEx(const char *fileName, int fontSize, const int *codepoints, int codepointCount); // Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height
|
||||
RLAPI Font LoadFontFromImage(Image image, Color key, int firstChar); // Load font from Image (XNA style)
|
||||
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
|
||||
RLAPI Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount); // Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
|
||||
RLAPI bool IsFontValid(Font font); // Check if a font is valid (font data loaded, WARNING: GPU texture not checked)
|
||||
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type); // Load font data for further use
|
||||
RLAPI GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount, int type); // Load font data for further use
|
||||
RLAPI Image GenImageFontAtlas(const GlyphInfo *glyphs, Rectangle **glyphRecs, int glyphCount, int fontSize, int padding, int packMethod); // Generate image font atlas using chars info
|
||||
RLAPI void UnloadFontData(GlyphInfo *glyphs, int glyphCount); // Unload font chars info data (RAM)
|
||||
RLAPI void UnloadFont(Font font); // Unload font from GPU memory (VRAM)
|
||||
|
|
@ -1506,6 +1506,8 @@ RLAPI const char *CodepointToUTF8(int codepoint, int *utf8Size);
|
|||
// Text strings management functions (no UTF-8 strings, only byte chars)
|
||||
// WARNING 1: Most of these functions use internal static buffers, it's recommended to store returned data on user-side for re-use
|
||||
// WARNING 2: Some strings allocate memory internally for the returned strings, those strings must be free by user using MemFree()
|
||||
RLAPI char **LoadTextLines(const char *text, int *count); // Load text as separate lines ('\n')
|
||||
RLAPI void UnloadTextLines(char **text); // Unload text lines
|
||||
RLAPI int TextCopy(char *dst, const char *src); // Copy one string to another, returns bytes copied
|
||||
RLAPI bool TextIsEqual(const char *text1, const char *text2); // Check if two text string are equal
|
||||
RLAPI unsigned int TextLength(const char *text); // Get text length, checks for '\0' ending
|
||||
|
|
@ -1522,7 +1524,6 @@ RLAPI char *TextToLower(const char *text);
|
|||
RLAPI char *TextToPascal(const char *text); // Get Pascal case notation version of provided string
|
||||
RLAPI char *TextToSnake(const char *text); // Get Snake case notation version of provided string
|
||||
RLAPI char *TextToCamel(const char *text); // Get Camel case notation version of provided string
|
||||
|
||||
RLAPI int TextToInteger(const char *text); // Get integer value from text
|
||||
RLAPI float TextToFloat(const char *text); // Get float value from text
|
||||
|
||||
|
|
|
|||
|
|
@ -3243,6 +3243,7 @@ unsigned int rlLoadTexture(const void *data, int width, int height, int format,
|
|||
int mipWidth = width;
|
||||
int mipHeight = height;
|
||||
int mipOffset = 0; // Mipmap data offset, only used for tracelog
|
||||
(void)mipOffset; // Used to avoid gcc warnings about unused variable
|
||||
|
||||
// NOTE: Added pointer math separately from function to avoid UBSAN complaining
|
||||
unsigned char *dataPtr = NULL;
|
||||
|
|
|
|||
|
|
@ -3722,7 +3722,7 @@ void GenMeshTangents(Mesh *mesh)
|
|||
}
|
||||
|
||||
// Gram-Schmidt orthogonalization to make tangent orthogonal to normal
|
||||
// T_prime = T - N * dot(N, T)
|
||||
// T_prime = T - N*dot(N, T)
|
||||
Vector3 orthogonalized = Vector3Subtract(tangent, Vector3Scale(normal, Vector3DotProduct(normal, tangent)));
|
||||
|
||||
// Handle cases where orthogonalized vector is too small
|
||||
|
|
|
|||
44
src/rtext.c
44
src/rtext.c
|
|
@ -147,7 +147,7 @@ static int textLineSpacing = 2; // Text vertical line spacing in
|
|||
static Font LoadBMFont(const char *fileName); // Load a BMFont file (AngelCode font file)
|
||||
#endif
|
||||
#if defined(SUPPORT_FILEFORMAT_BDF)
|
||||
static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, int *codepoints, int codepointCount, int *outFontSize);
|
||||
static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, const int *codepoints, int codepointCount, int *outFontSize);
|
||||
#endif
|
||||
|
||||
#if defined(SUPPORT_DEFAULT_FONT)
|
||||
|
|
@ -404,7 +404,7 @@ Font LoadFont(const char *fileName)
|
|||
// Load Font from TTF or BDF font file with generation parameters
|
||||
// NOTE: You can pass an array with desired characters, those characters should be available in the font
|
||||
// if array is NULL, default char set is selected 32..126
|
||||
Font LoadFontEx(const char *fileName, int fontSize, int *codepoints, int codepointCount)
|
||||
Font LoadFontEx(const char *fileName, int fontSize, const int *codepoints, int codepointCount)
|
||||
{
|
||||
Font font = { 0 };
|
||||
|
||||
|
|
@ -549,7 +549,7 @@ Font LoadFontFromImage(Image image, Color key, int firstChar)
|
|||
}
|
||||
|
||||
// Load font from memory buffer, fileType refers to extension: i.e. ".ttf"
|
||||
Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount)
|
||||
Font LoadFontFromMemory(const char *fileType, const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount)
|
||||
{
|
||||
Font font = { 0 };
|
||||
|
||||
|
|
@ -620,7 +620,7 @@ bool IsFontValid(Font font)
|
|||
|
||||
// Load font data for further use
|
||||
// NOTE: Requires TTF font memory data and can generate SDF data
|
||||
GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, int *codepoints, int codepointCount, int type)
|
||||
GlyphInfo *LoadFontData(const unsigned char *fileData, int dataSize, int fontSize, const int *codepoints, int codepointCount, int type)
|
||||
{
|
||||
// NOTE: Using some SDF generation default values,
|
||||
// trades off precision with ability to handle *smaller* sizes
|
||||
|
|
@ -1415,6 +1415,40 @@ Rectangle GetGlyphAtlasRec(Font font, int codepoint)
|
|||
//----------------------------------------------------------------------------------
|
||||
// Text strings management functions
|
||||
//----------------------------------------------------------------------------------
|
||||
// Load text as separate lines ('\n')
|
||||
// WARNING: There is a limit set for number of lines and line-size
|
||||
char **LoadTextLines(const char *text, int *count)
|
||||
{
|
||||
#define MAX_TEXTLINES_COUNT 512
|
||||
#define MAX_TEXTLINES_LINE_LEN 512
|
||||
|
||||
char **lines = (char **)RL_CALLOC(MAX_TEXTLINES_COUNT, sizeof(char *));
|
||||
for (int i = 0; i < MAX_TEXTLINES_COUNT; i++) lines[i] = (char *)RL_CALLOC(MAX_TEXTLINES_LINE_LEN, 1);
|
||||
int textSize = (int)strlen(text);
|
||||
int k = 0;
|
||||
|
||||
for (int i = 0, len = 0; (i < textSize) && (k < MAX_TEXTLINES_COUNT); i++)
|
||||
{
|
||||
if ((text[i] == '\n') || (len == (MAX_TEXTLINES_LINE_LEN - 1)))
|
||||
{
|
||||
strncpy(lines[k], &text[i - len], len);
|
||||
len = 0;
|
||||
k++;
|
||||
}
|
||||
else len++;
|
||||
}
|
||||
|
||||
*count += k;
|
||||
return lines;
|
||||
}
|
||||
|
||||
// Unload text lines
|
||||
void UnloadTextLines(char **lines)
|
||||
{
|
||||
for (int i = 0; i < MAX_TEXTLINES_COUNT; i++) RL_FREE(lines[i]);
|
||||
RL_FREE(lines);
|
||||
}
|
||||
|
||||
// Get text length in bytes, check for \0 character
|
||||
unsigned int TextLength(const char *text)
|
||||
{
|
||||
|
|
@ -2358,7 +2392,7 @@ static unsigned char HexToInt(char hex)
|
|||
|
||||
// Load font data for further use
|
||||
// NOTE: Requires BDF font memory data
|
||||
static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, int *codepoints, int codepointCount, int *outFontSize)
|
||||
static GlyphInfo *LoadFontDataBDF(const unsigned char *fileData, int dataSize, const int *codepoints, int codepointCount, int *outFontSize)
|
||||
{
|
||||
#define MAX_BUFFER_SIZE 256
|
||||
|
||||
|
|
|
|||
|
|
@ -1713,7 +1713,7 @@ Image ImageFromChannel(Image image, int selectedChannel)
|
|||
}
|
||||
|
||||
// Resize and image to new size using Nearest-Neighbor scaling algorithm
|
||||
void ImageResizeNN(Image *image,int newWidth,int newHeight)
|
||||
void ImageResizeNN(Image *image, int newWidth, int newHeight)
|
||||
{
|
||||
// Security check to avoid program crash
|
||||
if ((image->data == NULL) || (image->width == 0) || (image->height == 0)) return;
|
||||
|
|
|
|||
|
|
@ -9041,7 +9041,7 @@
|
|||
"name": "fontSize"
|
||||
},
|
||||
{
|
||||
"type": "int *",
|
||||
"type": "const int *",
|
||||
"name": "codepoints"
|
||||
},
|
||||
{
|
||||
|
|
@ -9091,7 +9091,7 @@
|
|||
"name": "fontSize"
|
||||
},
|
||||
{
|
||||
"type": "int *",
|
||||
"type": "const int *",
|
||||
"name": "codepoints"
|
||||
},
|
||||
{
|
||||
|
|
@ -9129,7 +9129,7 @@
|
|||
"name": "fontSize"
|
||||
},
|
||||
{
|
||||
"type": "int *",
|
||||
"type": "const int *",
|
||||
"name": "codepoints"
|
||||
},
|
||||
{
|
||||
|
|
@ -9605,6 +9605,32 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "LoadTextLines",
|
||||
"description": "Load text as separate lines ('\\n')",
|
||||
"returnType": "char **",
|
||||
"params": [
|
||||
{
|
||||
"type": "const char *",
|
||||
"name": "text"
|
||||
},
|
||||
{
|
||||
"type": "int *",
|
||||
"name": "count"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "UnloadTextLines",
|
||||
"description": "Unload text lines",
|
||||
"returnType": "void",
|
||||
"params": [
|
||||
{
|
||||
"type": "char **",
|
||||
"name": "text"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "TextCopy",
|
||||
"description": "Copy one string to another, returns bytes copied",
|
||||
|
|
|
|||
|
|
@ -6550,7 +6550,7 @@ return {
|
|||
params = {
|
||||
{type = "const char *", name = "fileName"},
|
||||
{type = "int", name = "fontSize"},
|
||||
{type = "int *", name = "codepoints"},
|
||||
{type = "const int *", name = "codepoints"},
|
||||
{type = "int", name = "codepointCount"}
|
||||
}
|
||||
},
|
||||
|
|
@ -6573,7 +6573,7 @@ return {
|
|||
{type = "const unsigned char *", name = "fileData"},
|
||||
{type = "int", name = "dataSize"},
|
||||
{type = "int", name = "fontSize"},
|
||||
{type = "int *", name = "codepoints"},
|
||||
{type = "const int *", name = "codepoints"},
|
||||
{type = "int", name = "codepointCount"}
|
||||
}
|
||||
},
|
||||
|
|
@ -6593,7 +6593,7 @@ return {
|
|||
{type = "const unsigned char *", name = "fileData"},
|
||||
{type = "int", name = "dataSize"},
|
||||
{type = "int", name = "fontSize"},
|
||||
{type = "int *", name = "codepoints"},
|
||||
{type = "const int *", name = "codepoints"},
|
||||
{type = "int", name = "codepointCount"},
|
||||
{type = "int", name = "type"}
|
||||
}
|
||||
|
|
@ -6845,6 +6845,23 @@ return {
|
|||
{type = "int *", name = "utf8Size"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "LoadTextLines",
|
||||
description = "Load text as separate lines ('\\n')",
|
||||
returnType = "char **",
|
||||
params = {
|
||||
{type = "const char *", name = "text"},
|
||||
{type = "int *", name = "count"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "UnloadTextLines",
|
||||
description = "Unload text lines",
|
||||
returnType = "void",
|
||||
params = {
|
||||
{type = "char **", name = "text"}
|
||||
}
|
||||
},
|
||||
{
|
||||
name = "TextCopy",
|
||||
description = "Copy one string to another, returns bytes copied",
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -679,7 +679,7 @@
|
|||
<Param type="unsigned int" name="frames" desc="" />
|
||||
</Callback>
|
||||
</Callbacks>
|
||||
<Functions count="584">
|
||||
<Functions count="586">
|
||||
<Function name="InitWindow" retType="void" paramCount="3" desc="Initialize window and OpenGL context">
|
||||
<Param type="int" name="width" desc="" />
|
||||
<Param type="int" name="height" desc="" />
|
||||
|
|
@ -2286,7 +2286,7 @@
|
|||
<Function name="LoadFontEx" retType="Font" paramCount="4" desc="Load font from file with extended parameters, use NULL for codepoints and 0 for codepointCount to load the default character set, font size is provided in pixels height">
|
||||
<Param type="const char *" name="fileName" desc="" />
|
||||
<Param type="int" name="fontSize" desc="" />
|
||||
<Param type="int *" name="codepoints" desc="" />
|
||||
<Param type="const int *" name="codepoints" desc="" />
|
||||
<Param type="int" name="codepointCount" desc="" />
|
||||
</Function>
|
||||
<Function name="LoadFontFromImage" retType="Font" paramCount="3" desc="Load font from Image (XNA style)">
|
||||
|
|
@ -2299,7 +2299,7 @@
|
|||
<Param type="const unsigned char *" name="fileData" desc="" />
|
||||
<Param type="int" name="dataSize" desc="" />
|
||||
<Param type="int" name="fontSize" desc="" />
|
||||
<Param type="int *" name="codepoints" desc="" />
|
||||
<Param type="const int *" name="codepoints" desc="" />
|
||||
<Param type="int" name="codepointCount" desc="" />
|
||||
</Function>
|
||||
<Function name="IsFontValid" retType="bool" paramCount="1" desc="Check if a font is valid (font data loaded, WARNING: GPU texture not checked)">
|
||||
|
|
@ -2309,7 +2309,7 @@
|
|||
<Param type="const unsigned char *" name="fileData" desc="" />
|
||||
<Param type="int" name="dataSize" desc="" />
|
||||
<Param type="int" name="fontSize" desc="" />
|
||||
<Param type="int *" name="codepoints" desc="" />
|
||||
<Param type="const int *" name="codepoints" desc="" />
|
||||
<Param type="int" name="codepointCount" desc="" />
|
||||
<Param type="int" name="type" desc="" />
|
||||
</Function>
|
||||
|
|
@ -2435,6 +2435,13 @@
|
|||
<Param type="int" name="codepoint" desc="" />
|
||||
<Param type="int *" name="utf8Size" desc="" />
|
||||
</Function>
|
||||
<Function name="LoadTextLines" retType="char **" paramCount="2" desc="Load text as separate lines ('\n')">
|
||||
<Param type="const char *" name="text" desc="" />
|
||||
<Param type="int *" name="count" desc="" />
|
||||
</Function>
|
||||
<Function name="UnloadTextLines" retType="void" paramCount="1" desc="Unload text lines">
|
||||
<Param type="char **" name="text" desc="" />
|
||||
</Function>
|
||||
<Function name="TextCopy" retType="int" paramCount="2" desc="Copy one string to another, returns bytes copied">
|
||||
<Param type="char *" name="dst" desc="" />
|
||||
<Param type="const char *" name="src" desc="" />
|
||||
|
|
|
|||
|
|
@ -148,11 +148,6 @@ static int UpdateRequiredFiles(void);
|
|||
static rlExampleInfo *LoadExamplesData(const char *fileName, const char *category, bool sort, int *exCount);
|
||||
static void UnloadExamplesData(rlExampleInfo *exInfo);
|
||||
|
||||
// Get text lines (by line-breaks '\n')
|
||||
// WARNING: It does not copy text data, just returns line pointers
|
||||
static char **LoadTextLines(const char *text, int *count);
|
||||
static void UnloadTextLines(char **text);
|
||||
|
||||
// Load example info from file header
|
||||
static rlExampleInfo *LoadExampleInfo(const char *exFileName);
|
||||
static void UnloadExampleInfo(rlExampleInfo *exInfo);
|
||||
|
|
@ -1775,39 +1770,6 @@ static int FileMove(const char *srcPath, const char *dstPath)
|
|||
return result;
|
||||
}
|
||||
|
||||
// Load text lines
|
||||
static char **LoadTextLines(const char *text, int *count)
|
||||
{
|
||||
#define MAX_TEXT_LINES 512
|
||||
#define MAX_TEXT_LINE_LEN 512
|
||||
|
||||
char **lines = (char **)RL_CALLOC(MAX_TEXT_LINES, sizeof(char *));
|
||||
for (int i = 0; i < MAX_TEXT_LINES; i++) lines[i] = (char *)RL_CALLOC(MAX_TEXT_LINE_LEN, 1);
|
||||
int textSize = (int)strlen(text);
|
||||
int k = 0;
|
||||
|
||||
for (int i = 0, len = 0; (i < textSize) && (k < MAX_TEXT_LINES); i++)
|
||||
{
|
||||
if ((text[i] == '\n') || (len == (MAX_TEXT_LINE_LEN - 1)))
|
||||
{
|
||||
strncpy(lines[k], &text[i - len], len);
|
||||
len = 0;
|
||||
k++;
|
||||
}
|
||||
else len++;
|
||||
}
|
||||
|
||||
*count += k;
|
||||
return lines;
|
||||
}
|
||||
|
||||
// Unload text lines
|
||||
static void UnloadTextLines(char **lines)
|
||||
{
|
||||
for (int i = 0; i < MAX_TEXT_LINES; i++) RL_FREE(lines[i]);
|
||||
RL_FREE(lines);
|
||||
}
|
||||
|
||||
// Get example info from example file header
|
||||
// NOTE: Expecting the example to follow raylib_example_template.c
|
||||
rlExampleInfo *LoadExampleInfo(const char *exFileName)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user