Compare commits
76 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4d18b2d1c | ||
|
|
3cd4d3179d | ||
|
|
6ecc0455eb | ||
|
|
d9933008f5 | ||
|
|
163b1ef2e9 | ||
|
|
1e257d1738 | ||
|
|
a1d02a5ec8 | ||
|
|
0248dc6e98 | ||
|
|
d64fc43f38 | ||
|
|
39ce5d4a8e | ||
|
|
33f216d4fc | ||
|
|
651b37a025 | ||
|
|
c84506a92d | ||
|
|
9ad8b8ba74 | ||
|
|
c7ea429994 | ||
|
|
ed42d5dbdc | ||
|
|
c5d9cf405d | ||
|
|
acd5507b0e | ||
|
|
b44a355a81 | ||
|
|
df70c5c952 | ||
|
|
4bb5254d6b | ||
|
|
e623387b8c | ||
|
|
166996bccc | ||
|
|
42956d00c0 | ||
|
|
d39c75c234 | ||
|
|
180d2e04de | ||
|
|
10c8f7d7ad | ||
|
|
6efd4175ef | ||
|
|
a787270fea | ||
|
|
6ab4e51407 | ||
|
|
3c33e0469f | ||
|
|
55937dd8a9 | ||
|
|
492e809dd5 | ||
|
|
178530d5f5 | ||
|
|
dfea9ed840 | ||
|
|
125ead95a3 | ||
|
|
813f0323af | ||
|
|
346e87c8aa | ||
|
|
be3790195a | ||
|
|
52767eb8ae | ||
|
|
b7d89cb7b9 | ||
|
|
7bdb0cd320 | ||
|
|
a6e9ce520f | ||
|
|
3eee232f10 | ||
|
|
22bb251252 | ||
|
|
ac0b07c4bd | ||
|
|
e8167c2e56 | ||
|
|
14f49a38dd | ||
|
|
5013830647 | ||
|
|
97cb212bf0 | ||
|
|
3bf08a304c | ||
|
|
2e60ac0127 | ||
|
|
0de5f8aed0 | ||
|
|
67fd5af55a | ||
|
|
f4b69764db | ||
|
|
d6c77762cb | ||
|
|
c30197911a | ||
|
|
a00552ea79 | ||
|
|
e072ff119b | ||
|
|
dfe22275cf | ||
|
|
8d5a7d382c | ||
|
|
d4fc514d54 | ||
|
|
03ec79ef85 | ||
|
|
17a1754271 | ||
|
|
a7f626993c | ||
|
|
5bbafa4f86 | ||
|
|
b6af3509c8 | ||
|
|
e18e2db5e5 | ||
|
|
1a9b848c06 | ||
|
|
279bcc0a13 | ||
|
|
9444b5a438 | ||
|
|
57a8a21b48 | ||
|
|
9e69ca5946 | ||
|
|
1b6a05ca3b | ||
|
|
ae7cb3fa93 | ||
|
|
ae76994a2d |
82
README.md
@ -1,12 +1,12 @@
|
||||

|
||||

|
||||
|
||||
# raylib-zig
|
||||
|
||||
Manually tweaked, auto-generated [raylib](https://github.com/raysan5/raylib) bindings for zig.
|
||||
|
||||
Bindings tested on raylib version 5.5 and Zig 0.13.0
|
||||
Bindings tested on raylib version 5.6-dev and Zig 0.15.1
|
||||
|
||||
Thanks to all the [contributors](https://github.com/Not-Nik/raylib-zig/graphs/contributors) for their help with this
|
||||
Thanks to all the [contributors](https://github.com/raylib-zig/raylib-zig/graphs/contributors) for their help with this
|
||||
binding.
|
||||
|
||||
## Example
|
||||
@ -38,9 +38,9 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.white);
|
||||
rl.clearBackground(.white);
|
||||
|
||||
rl.drawText("Congrats! You created your first window!", 190, 200, 20, rl.Color.light_gray);
|
||||
rl.drawText("Congrats! You created your first window!", 190, 200, 20, .light_gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
@ -55,22 +55,22 @@ want to run an example, say `basic_window` run `zig build basic_window`
|
||||
|
||||
### Using raylib-zig's template
|
||||
|
||||
* Execute `project_setup.sh project_name`, this will create a folder with the name specified
|
||||
* You can copy that folder anywhere you want and edit the source
|
||||
* Run `zig build run` at any time to test your project
|
||||
- Execute `project_setup.sh project_name`, this will create a folder with the name specified
|
||||
- You can copy that folder anywhere you want and edit the source
|
||||
- Run `zig build run` at any time to test your project
|
||||
|
||||
### In an existing project (e.g. created with `zig init`)
|
||||
|
||||
Download and add raylib-zig as a dependency by running the following command in your project root:
|
||||
|
||||
```
|
||||
zig fetch --save git+https://github.com/Not-Nik/raylib-zig#devel
|
||||
zig fetch --save git+https://github.com/raylib-zig/raylib-zig#devel
|
||||
```
|
||||
|
||||
Then add raylib-zig as a dependency and import its modules and artifact in your `build.zig`:
|
||||
|
||||
```zig
|
||||
const raylib_dep = b.dependency("raylib-zig", .{
|
||||
const raylib_dep = b.dependency("raylib_zig", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
@ -88,8 +88,8 @@ exe.root_module.addImport("raylib", raylib);
|
||||
exe.root_module.addImport("raygui", raygui);
|
||||
```
|
||||
|
||||
If you additionally want to support Web as a platform with emscripten, you will need to use `emcc.zig` by importing
|
||||
raylib-zig's build script with `const rlz = @import("raylib-zig");` and then accessing its functions with `rlz.emcc`.
|
||||
If you additionally want to support Web as a platform with emscripten, you will need to use `emsdk` by importing
|
||||
raylib-zig's build script with `const rlz = @import("raylib_zig");` and then accessing like described here [Exporting for web](https://github.com/raylib-zig/raylib-zig?tab=readme-ov-file#exporting-for-web).
|
||||
Refer to raylib-zig's project template on how to use them.
|
||||
|
||||
### Passing build options
|
||||
@ -98,10 +98,10 @@ raylib allows customisations of certain parts of its build process such as choos
|
||||
shared library or not including certain modules. You can optionally pass these options to raylib-zig dependency like so
|
||||
|
||||
```zig
|
||||
const raylib_dep = b.dependency("raylib-zig", .{
|
||||
const raylib_dep = b.dependency("raylib_zig", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.shared = true, // Build raylib as a shared library
|
||||
.linkage = .dynamic, // Build raylib as a shared library
|
||||
.opengl_version = rlz.OpenglVersion.gl_2_1, // Use OpenGL 2.1 (requires importing raylib-zig's build script)
|
||||
});
|
||||
```
|
||||
@ -113,21 +113,55 @@ fonts, 3D models and audio, linkage variants. You can specify these options for
|
||||
corresponding C macro before you link with it, e.g.:
|
||||
|
||||
```zig
|
||||
raylib_artifact.defineCMacro("SUPPORT_FILEFORMAT_JPG", null);
|
||||
raylib_artifact.root_module.addCMacro("SUPPORT_FILEFORMAT_JPG", "");
|
||||
```
|
||||
|
||||
## Exporting for web
|
||||
|
||||
To export your project for the web, first install emsdk.
|
||||
Once emsdk is installed, set it up by running
|
||||
To export your project for the web, first add emsdk to your dependencies.
|
||||
Its also possible to use a local emsdk folder.
|
||||
|
||||
`emsdk install latest`
|
||||
`zig fetch --save=emsdk git+https://github.com/emscripten-core/emsdk#4.0.9`
|
||||
|
||||
Find the folder where it's installed and run
|
||||
Add this to your build method to build for the web
|
||||
|
||||
`zig build -Dtarget=wasm32-emscripten --sysroot [path to emsdk]/upstream/emscripten`
|
||||
```zig
|
||||
if (target.query.os_tag == .emscripten) {
|
||||
const emsdk = rlz.emsdk;
|
||||
const wasm = b.addLibrary(.{
|
||||
.name = <your_project_name>,
|
||||
.root_module = exe_mod,
|
||||
});
|
||||
|
||||
once that is finished, the exported project should be located at `zig-out/htmlout`
|
||||
const install_dir: std.Build.InstallDir = .{ .custom = "web" };
|
||||
const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{ .optimize = optimize });
|
||||
const emcc_settings = emsdk.emccDefaultSettings(b.allocator, .{ .optimize = optimize });
|
||||
|
||||
const emcc_step = emsdk.emccStep(b, raylib_artifact, wasm, .{
|
||||
.optimize = optimize,
|
||||
.flags = emcc_flags,
|
||||
.settings = emcc_settings,
|
||||
.install_dir = install_dir,
|
||||
});
|
||||
b.getInstallStep().dependOn(emcc_step);
|
||||
|
||||
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),
|
||||
&.{},
|
||||
);
|
||||
|
||||
emrun_step.dependOn(emcc_step);
|
||||
run_step.dependOn(emrun_step);
|
||||
}
|
||||
```
|
||||
|
||||
then you can run
|
||||
|
||||
`zig build -Dtarget=wasm32-emscripten`
|
||||
|
||||
once that is finished, the exported project should be located at `zig-out/web`
|
||||
|
||||
### When is the binding updated?
|
||||
|
||||
@ -136,6 +170,6 @@ implementation stuff should be updatable with some hacks on your side.
|
||||
|
||||
### What needs to be done?
|
||||
|
||||
+ _(Done)_ Set up a proper package build and a build script for the examples
|
||||
+ Port all the examples
|
||||
+ Member functions/initialisers
|
||||
- _(Done)_ Set up a proper package build and a build script for the examples
|
||||
- Port all the examples
|
||||
- Member functions/initialisers
|
||||
|
||||
393
build.zig
@ -3,39 +3,12 @@
|
||||
const std = @import("std");
|
||||
const this = @This();
|
||||
const rl = @import("raylib");
|
||||
pub const emsdk = rl.emsdk;
|
||||
|
||||
pub const emcc = @import("emcc.zig");
|
||||
|
||||
pub const Options = struct {
|
||||
raudio: bool = true,
|
||||
rmodels: bool = true,
|
||||
rshapes: bool = true,
|
||||
rtext: bool = true,
|
||||
rtextures: bool = true,
|
||||
platform: PlatformBackend = .glfw,
|
||||
shared: bool = false,
|
||||
linux_display_backend: LinuxDisplayBackend = .X11,
|
||||
opengl_version: OpenglVersion = .auto,
|
||||
};
|
||||
|
||||
pub const OpenglVersion = enum {
|
||||
auto,
|
||||
gl_1_1,
|
||||
gl_2_1,
|
||||
gl_3_3,
|
||||
gl_4_3,
|
||||
gles_2,
|
||||
gles_3,
|
||||
};
|
||||
|
||||
pub const LinuxDisplayBackend = enum { X11, Wayland, Both };
|
||||
|
||||
pub const PlatformBackend = enum {
|
||||
glfw,
|
||||
rgfw,
|
||||
sdl,
|
||||
drm,
|
||||
};
|
||||
pub const Options = rl.Options;
|
||||
pub const OpenglVersion = rl.OpenglVersion;
|
||||
pub const LinuxDisplayBackend = rl.LinuxDisplayBackend;
|
||||
pub const PlatformBackend = rl.PlatformBackend;
|
||||
|
||||
const Program = struct {
|
||||
name: []const u8,
|
||||
@ -43,117 +16,34 @@ const Program = struct {
|
||||
desc: []const u8,
|
||||
};
|
||||
|
||||
fn link(
|
||||
b: *std.Build,
|
||||
exe: *std.Build.Step.Compile,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.OptimizeMode,
|
||||
options: Options,
|
||||
) !void {
|
||||
const lib = try getRaylib(b, target, optimize, options);
|
||||
fn getRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) *std.Build.Step.Compile {
|
||||
const raylib_dep = b.dependency("raylib", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.raudio = options.raudio,
|
||||
.rmodels = options.rmodels,
|
||||
.rshapes = options.rshapes,
|
||||
.rtext = options.rtext,
|
||||
.rtextures = options.rtextures,
|
||||
.platform = options.platform,
|
||||
.linkage = options.linkage,
|
||||
.linux_display_backend = options.linux_display_backend,
|
||||
.opengl_version = options.opengl_version,
|
||||
.android_api_version = options.android_api_version,
|
||||
.android_ndk = options.android_ndk,
|
||||
});
|
||||
|
||||
const target_os = exe.rootModuleTarget().os.tag;
|
||||
switch (target_os) {
|
||||
.windows => {
|
||||
exe.linkSystemLibrary("winmm");
|
||||
exe.linkSystemLibrary("gdi32");
|
||||
exe.linkSystemLibrary("opengl32");
|
||||
},
|
||||
.macos => {
|
||||
exe.linkFramework("OpenGL");
|
||||
exe.linkFramework("Cocoa");
|
||||
exe.linkFramework("IOKit");
|
||||
exe.linkFramework("CoreAudio");
|
||||
exe.linkFramework("CoreVideo");
|
||||
},
|
||||
.freebsd, .openbsd, .netbsd, .dragonfly => {
|
||||
exe.linkSystemLibrary("GL");
|
||||
exe.linkSystemLibrary("rt");
|
||||
exe.linkSystemLibrary("dl");
|
||||
exe.linkSystemLibrary("m");
|
||||
exe.linkSystemLibrary("X11");
|
||||
exe.linkSystemLibrary("Xrandr");
|
||||
exe.linkSystemLibrary("Xinerama");
|
||||
exe.linkSystemLibrary("Xi");
|
||||
exe.linkSystemLibrary("Xxf86vm");
|
||||
exe.linkSystemLibrary("Xcursor");
|
||||
},
|
||||
.emscripten, .wasi => {
|
||||
// When using emscripten, the libries don't need to be linked
|
||||
// because emscripten is going to do that later.
|
||||
},
|
||||
else => { // Linux and possibly others.
|
||||
exe.linkSystemLibrary("GL");
|
||||
exe.linkSystemLibrary("rt");
|
||||
exe.linkSystemLibrary("dl");
|
||||
exe.linkSystemLibrary("m");
|
||||
exe.linkSystemLibrary("X11");
|
||||
},
|
||||
}
|
||||
const raylib = raylib_dep.artifact("raylib");
|
||||
|
||||
exe.linkLibrary(lib);
|
||||
}
|
||||
const raygui_dep = b.dependency("raygui", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
var _raylib_lib_cache: ?*std.Build.Step.Compile = null;
|
||||
fn getRaylib(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, options: Options) !*std.Build.Step.Compile {
|
||||
if (_raylib_lib_cache) |lib| return lib else {
|
||||
const raylib = b.dependency("raylib", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.raudio = options.raudio,
|
||||
.rmodels = options.rmodels,
|
||||
.rshapes = options.rshapes,
|
||||
.rtext = options.rtext,
|
||||
.rtextures = options.rtextures,
|
||||
.platform = options.platform,
|
||||
.shared = options.shared,
|
||||
.linux_display_backend = options.linux_display_backend,
|
||||
.opengl_version = options.opengl_version,
|
||||
});
|
||||
rl.addRaygui(b, raylib, raygui_dep, options);
|
||||
|
||||
const lib = raylib.artifact("raylib");
|
||||
|
||||
const raygui_dep = b.dependency("raygui", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
var gen_step = b.addWriteFiles();
|
||||
lib.step.dependOn(&gen_step.step);
|
||||
|
||||
const raygui_c_path = gen_step.add("raygui.c", "#define RAYGUI_IMPLEMENTATION\n#include \"raygui.h\"\n");
|
||||
|
||||
var raylib_flags_arr = std.ArrayList([]const u8).init(b.allocator);
|
||||
defer raylib_flags_arr.deinit();
|
||||
|
||||
try raylib_flags_arr.appendSlice(&[_][]const u8{
|
||||
"-std=gnu99",
|
||||
"-D_GNU_SOURCE",
|
||||
"-DGL_SILENCE_DEPRECATION=199309L",
|
||||
"-fno-sanitize=undefined", // https://github.com/raysan5/raylib/issues/3674
|
||||
});
|
||||
|
||||
if (options.shared) {
|
||||
try raylib_flags_arr.appendSlice(&[_][]const u8{
|
||||
"-fPIC",
|
||||
"-DBUILD_LIBTYPE_SHARED",
|
||||
});
|
||||
}
|
||||
|
||||
lib.addCSourceFile(.{
|
||||
.file = raygui_c_path,
|
||||
.flags = raylib_flags_arr.items,
|
||||
});
|
||||
|
||||
lib.addIncludePath(raylib.path("src"));
|
||||
lib.addIncludePath(raygui_dep.path("src"));
|
||||
|
||||
lib.installHeader(raygui_dep.path("src/raygui.h"), "raygui.h");
|
||||
|
||||
b.installArtifact(lib);
|
||||
_raylib_lib_cache = lib;
|
||||
return lib;
|
||||
}
|
||||
b.installArtifact(raylib);
|
||||
return raylib;
|
||||
}
|
||||
|
||||
fn getModule(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Module {
|
||||
@ -183,18 +73,11 @@ pub fn build(b: *std.Build) !void {
|
||||
const target = b.standardTargetOptions(.{});
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const defaults = Options{};
|
||||
const options = Options{
|
||||
.platform = b.option(PlatformBackend, "platform", "Compile raylib in native mode (no X11)") orelse defaults.platform,
|
||||
.raudio = b.option(bool, "raudio", "Compile with audio support") orelse defaults.raudio,
|
||||
.rmodels = b.option(bool, "rmodels", "Compile with models support") orelse defaults.rmodels,
|
||||
.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,
|
||||
.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,
|
||||
};
|
||||
const raylib_artifact = this.getRaylib(b, target, optimize, Options.getOptions(b));
|
||||
const raylib = this.getModule(b, target, optimize);
|
||||
const raygui = this.gui.getModule(b, target, optimize);
|
||||
|
||||
raylib.linkLibrary(raylib_artifact);
|
||||
|
||||
const examples = [_]Program{
|
||||
.{
|
||||
@ -227,6 +110,16 @@ pub fn build(b: *std.Build) !void {
|
||||
.path = "examples/core/basic_window.zig",
|
||||
.desc = "Creates a basic window with text",
|
||||
},
|
||||
.{
|
||||
.name = "core_monitor_change",
|
||||
.path = "examples/core/core_monitor_change.zig",
|
||||
.desc = "Simple Monitor Manager",
|
||||
},
|
||||
.{
|
||||
.name = "basic_window_web",
|
||||
.path = "examples/core/basic_window_web.zig",
|
||||
.desc = "Creates a basic window with text (web)",
|
||||
},
|
||||
.{
|
||||
.name = "input_keys",
|
||||
.path = "examples/core/input_keys.zig",
|
||||
@ -252,6 +145,11 @@ pub fn build(b: *std.Build) !void {
|
||||
.path = "examples/core/2d_camera.zig",
|
||||
.desc = "Shows the functionality of a 2D camera",
|
||||
},
|
||||
.{
|
||||
.name = "2d_camera_platformer",
|
||||
.path = "examples/core/2d_camera_platformer.zig",
|
||||
.desc = "2D camera platformer",
|
||||
},
|
||||
.{
|
||||
.name = "3d_camera_first_person",
|
||||
.path = "examples/core/3d_camera_first_person.zig",
|
||||
@ -272,16 +170,41 @@ pub fn build(b: *std.Build) !void {
|
||||
.path = "examples/core/3d_picking.zig",
|
||||
.desc = "Shows picking in 3d mode",
|
||||
},
|
||||
.{
|
||||
.name = "drop_files",
|
||||
.path = "examples/core/drop_files.zig",
|
||||
.desc = "Demonstrates how to implement a drop files functionality",
|
||||
},
|
||||
.{
|
||||
.name = "window_flags",
|
||||
.path = "examples/core/window_flags.zig",
|
||||
.desc = "Demonstrates various flags used during and after window creation",
|
||||
},
|
||||
.{
|
||||
.name = "gui_message_box",
|
||||
.path = "examples/gui/message_box.zig",
|
||||
.desc = "Demonstrates showing and hiding a message box",
|
||||
},
|
||||
.{
|
||||
.name = "raymarching",
|
||||
.path = "examples/shaders/raymarching.zig",
|
||||
.desc = "Uses a raymarching in a shader to render shapes",
|
||||
},
|
||||
.{
|
||||
.name = "shaders_ascii_rendering",
|
||||
.path = "examples/shaders/shaders_ascii_rendering.zig",
|
||||
.desc = "Post-processing to render in ASCII",
|
||||
},
|
||||
.{
|
||||
.name = "shaders_basic_pbr",
|
||||
.path = "examples/shaders/shaders_basic_pbr.zig",
|
||||
.desc = "Demonstrates physically based rendering",
|
||||
},
|
||||
.{
|
||||
.name = "shaders_hybrid_render",
|
||||
.path = "examples/shaders/shaders_hybrid_render.zig",
|
||||
.desc = "Demonstrates hybrid rendering",
|
||||
},
|
||||
.{
|
||||
.name = "texture_outline",
|
||||
.path = "examples/shaders/texture_outline.zig",
|
||||
@ -332,6 +255,21 @@ pub fn build(b: *std.Build) !void {
|
||||
.path = "examples/shapes/draw_ring.zig",
|
||||
.desc = "Dynaically renders a ring using raygui",
|
||||
},
|
||||
.{
|
||||
.name = "easings_ball_anim",
|
||||
.path = "examples/shapes/easings_ball_anim.zig",
|
||||
.desc = "Renders a ball that demonstrates various easing functions",
|
||||
},
|
||||
.{
|
||||
.name = "easings_box_anim",
|
||||
.path = "examples/shapes/easings_box_anim.zig",
|
||||
.desc = "Renders a box that demonstrates various easing functions",
|
||||
},
|
||||
.{
|
||||
.name = "easings_rectangle_array",
|
||||
.path = "examples/shapes/easings_rectangle_array.zig",
|
||||
.desc = "Renders a box that demonstrates various easing functions",
|
||||
},
|
||||
.{
|
||||
.name = "following_eyes",
|
||||
.path = "examples/shapes/following_eyes.zig",
|
||||
@ -347,6 +285,16 @@ pub fn build(b: *std.Build) !void {
|
||||
.path = "examples/shapes/rectangle_scaling.zig",
|
||||
.desc = "Renders a resizable rectangle",
|
||||
},
|
||||
.{
|
||||
.name = "splines_drawing",
|
||||
.path = "examples/shapes/splines_drawing.zig",
|
||||
.desc = "Renders a spline",
|
||||
},
|
||||
.{
|
||||
.name = "top_down_lights",
|
||||
.path = "examples/shapes/top_down_lights.zig",
|
||||
.desc = "Renders a sceen with shadows and a top down persepective",
|
||||
},
|
||||
.{
|
||||
.name = "sprite_anim",
|
||||
.path = "examples/textures/sprite_anim.zig",
|
||||
@ -358,18 +306,63 @@ pub fn build(b: *std.Build) !void {
|
||||
.desc = "Background scrolling & parallax demo",
|
||||
},
|
||||
.{
|
||||
.name = "text_format_text",
|
||||
.path = "examples/text/text_format_text.zig",
|
||||
.name = "codepoints_loading",
|
||||
.path = "examples/text/codepoints_loading.zig",
|
||||
.desc = "Renders UTF-8 text",
|
||||
},
|
||||
.{
|
||||
.name = "draw_3d",
|
||||
.path = "examples/text/draw_3d.zig",
|
||||
.desc = "Renders an example of text rendered in a 3d world",
|
||||
},
|
||||
.{
|
||||
.name = "font_filters",
|
||||
.path = "examples/text/font_filters.zig",
|
||||
.desc = "Demonstrates the various font filters",
|
||||
},
|
||||
.{
|
||||
.name = "font_loading",
|
||||
.path = "examples/text/font_loading.zig",
|
||||
.desc = "Demonstrates how to load fonts",
|
||||
},
|
||||
.{
|
||||
.name = "font_sdf",
|
||||
.path = "examples/text/font_sdf.zig",
|
||||
.desc = "Demonstrates rending a sdf font",
|
||||
},
|
||||
.{
|
||||
.name = "font_spritefont",
|
||||
.path = "examples/text/font_spritefont.zig",
|
||||
.desc = "Demonstrates rendering spritefonts",
|
||||
},
|
||||
.{
|
||||
.name = "format_text",
|
||||
.path = "examples/text/format_text.zig",
|
||||
.desc = "Renders variables as text",
|
||||
},
|
||||
.{
|
||||
.name = "text_raylib_fonts",
|
||||
.path = "examples/text/text_raylib_fonts.zig",
|
||||
.name = "input_box",
|
||||
.path = "examples/text/input_box.zig",
|
||||
.desc = "Show and example of an input_box",
|
||||
},
|
||||
.{
|
||||
.name = "raylib_fonts",
|
||||
.path = "examples/text/raylib_fonts.zig",
|
||||
.desc = "Show fonts included with raylib",
|
||||
},
|
||||
.{
|
||||
.name = "text_writing_anim",
|
||||
.path = "examples/text/text_writing_anim.zig",
|
||||
.name = "rectangle_bounds",
|
||||
.path = "examples/text/rectangle_bounds.zig",
|
||||
.desc = "demonstrate a flexible, resizeable, text box",
|
||||
},
|
||||
.{
|
||||
.name = "unicode",
|
||||
.path = "examples/text/unicode.zig",
|
||||
.desc = "demonstrate rendering of unicode",
|
||||
},
|
||||
.{
|
||||
.name = "writing_anim",
|
||||
.path = "examples/text/writing_anim.zig",
|
||||
.desc = "Simple text animation",
|
||||
},
|
||||
.{
|
||||
@ -377,12 +370,26 @@ pub fn build(b: *std.Build) !void {
|
||||
.path = "examples/textures/textures_image_loading.zig",
|
||||
.desc = "Image loading and texture creation",
|
||||
},
|
||||
|
||||
.{
|
||||
.name = "models_heightmap",
|
||||
.path = "examples/models/models_heightmap.zig",
|
||||
.desc = "Heightmap loading and drawing",
|
||||
},
|
||||
.{
|
||||
.name = "models_bone_socket",
|
||||
.path = "examples/models/models_bone_socket.zig",
|
||||
.desc = "Bone socket",
|
||||
},
|
||||
.{
|
||||
.name = "models_box_collisions",
|
||||
.path = "examples/models/models_box_collisions.zig",
|
||||
.desc = "Box collisions",
|
||||
},
|
||||
.{
|
||||
.name = "models_rlgl_solar_system",
|
||||
.path = "examples/models/models_rlgl_solar_system.zig",
|
||||
.desc = "Solar System",
|
||||
},
|
||||
// .{
|
||||
// .name = "shaders_basic_lighting",
|
||||
// .path = "examples/shaders/shaders_basic_lighting.zig",
|
||||
@ -390,20 +397,13 @@ pub fn build(b: *std.Build) !void {
|
||||
// },
|
||||
};
|
||||
|
||||
const raylib = this.getModule(b, target, optimize);
|
||||
const raygui = this.gui.getModule(b, target, optimize);
|
||||
|
||||
const raylib_test = b.addTest(.{
|
||||
.root_source_file = b.path("lib/raylib.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_module = raylib,
|
||||
});
|
||||
raylib_test.linkLibC();
|
||||
|
||||
const raygui_test = b.addTest(.{
|
||||
.root_source_file = b.path("lib/raygui.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
.root_module = raygui,
|
||||
});
|
||||
raygui_test.root_module.addImport("raylib-zig", raylib);
|
||||
raygui_test.linkLibC();
|
||||
@ -415,33 +415,54 @@ pub fn build(b: *std.Build) !void {
|
||||
const examples_step = b.step("examples", "Builds all the examples");
|
||||
|
||||
for (examples) |ex| {
|
||||
const mod = b.createModule(.{
|
||||
.root_source_file = b.path(ex.path),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
if (target.query.os_tag == .emscripten) {
|
||||
const exe_lib = try emcc.compileForEmscripten(b, ex.name, ex.path, target, optimize);
|
||||
exe_lib.root_module.addImport("raylib", raylib);
|
||||
exe_lib.root_module.addImport("raygui", raygui);
|
||||
const raylib_lib = try getRaylib(b, target, optimize, options);
|
||||
const wasm = b.addLibrary(.{
|
||||
.name = ex.name,
|
||||
.root_module = mod,
|
||||
});
|
||||
wasm.root_module.addImport("raylib", raylib);
|
||||
wasm.root_module.addImport("raygui", raygui);
|
||||
|
||||
// Note that raylib itself isn't actually added to the exe_lib
|
||||
// output file, so it also needs to be linked with emscripten.
|
||||
exe_lib.linkLibrary(raylib_lib);
|
||||
const link_step = try emcc.linkWithEmscripten(b, &[_]*std.Build.Step.Compile{ exe_lib, raylib_lib });
|
||||
link_step.addArg("--embed-file");
|
||||
link_step.addArg("resources/");
|
||||
const install_dir: std.Build.InstallDir = .{ .custom = "web" };
|
||||
const emcc_flags = emsdk.emccDefaultFlags(b.allocator, .{
|
||||
.optimize = optimize,
|
||||
.asyncify = !std.mem.endsWith(u8, ex.name, "web"),
|
||||
});
|
||||
const emcc_settings = emsdk.emccDefaultSettings(b.allocator, .{
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const emcc_step = emsdk.emccStep(b, raylib_artifact, wasm, .{
|
||||
.optimize = optimize,
|
||||
.flags = emcc_flags,
|
||||
.settings = emcc_settings,
|
||||
.shell_file_path = emsdk.shell(b),
|
||||
.install_dir = install_dir,
|
||||
.embed_paths = &.{.{ .src_path = "resources/" }},
|
||||
});
|
||||
|
||||
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),
|
||||
&.{},
|
||||
);
|
||||
emrun_step.dependOn(emcc_step);
|
||||
|
||||
const run_step = try emcc.emscriptenRunStep(b);
|
||||
run_step.step.dependOn(&link_step.step);
|
||||
const run_option = b.step(ex.name, ex.desc);
|
||||
|
||||
run_option.dependOn(&run_step.step);
|
||||
examples_step.dependOn(&exe_lib.step);
|
||||
run_option.dependOn(emrun_step);
|
||||
examples_step.dependOn(emcc_step);
|
||||
} else {
|
||||
const exe = b.addExecutable(.{
|
||||
.name = ex.name,
|
||||
.root_source_file = b.path(ex.path),
|
||||
.optimize = optimize,
|
||||
.target = target,
|
||||
.root_module = mod,
|
||||
});
|
||||
try this.link(b, exe, target, optimize, options);
|
||||
exe.root_module.addImport("raylib", raylib);
|
||||
exe.root_module.addImport("raygui", raygui);
|
||||
|
||||
|
||||
@ -1,17 +1,26 @@
|
||||
.{
|
||||
.name = "raylib-zig",
|
||||
.version = "5.5.0",
|
||||
.name = .raylib_zig,
|
||||
.version = "5.6.0-dev",
|
||||
.fingerprint = 0xc4cfa8c610114f28,
|
||||
.dependencies = .{
|
||||
.raylib = .{
|
||||
.url = "https://github.com/raysan5/raylib/archive/c1ab645ca298a2801097931d1079b10ff7eb9df8.tar.gz",
|
||||
.hash = "1220d93782859726c2c46a05450615b7edfc82b7319daac50cbc7c3345d660b022d7",
|
||||
.url = "git+https://github.com/raysan5/raylib#8ada37d9671682f420a2be1f1afd4b06173b81ad",
|
||||
.hash = "raylib-5.6.0-dev-whq8uCg2ywTzCiX3VEP9RuCMXR6_VnDBmkj8GjL_p5QN",
|
||||
},
|
||||
.raygui = .{
|
||||
.url = "https://github.com/raysan5/raygui/archive/1e03efca48c50c5ea4b4a053d5bf04bad58d3e43.tar.gz",
|
||||
.hash = "122062b24f031e68f0d11c91dfc32aed5baf06caf26ed3c80ea1802f9e788ef1c358",
|
||||
.url = "git+https://github.com/raysan5/raygui#9cdfec460b43a17264af3c181c46f62bf107ac17",
|
||||
.hash = "N-V-__8AALUbbwDKkSH4nbf3Ml_dTWo9qbELvle5i9eQZMuo",
|
||||
},
|
||||
.emsdk = .{
|
||||
.url = "git+https://github.com/emscripten-core/emsdk#4.0.9",
|
||||
.hash = "N-V-__8AAJl1DwBezhYo_VE6f53mPVm00R-Fk28NPW7P14EQ",
|
||||
},
|
||||
.zemscripten = .{
|
||||
.url = "git+https://github.com/zig-gamedev/zemscripten?ref=main#00da03b188220374a57cb34cda6230b8d53737ea",
|
||||
.hash = "zemscripten-0.2.0-dev-sRlDqFJSAAB8hgnRt5DDMKP3zLlDtMnUDwYRJVCa5lGY",
|
||||
},
|
||||
},
|
||||
.minimum_zig_version = "0.13.0",
|
||||
.minimum_zig_version = "0.15.1",
|
||||
.paths = .{
|
||||
"build.zig",
|
||||
"build.zig.zon",
|
||||
|
||||
135
emcc.zig
@ -1,135 +0,0 @@
|
||||
// raylib-zig (c) Nikolas Wipper 2020-2024
|
||||
|
||||
const std = @import("std");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const emccOutputDir = "zig-out" ++ std.fs.path.sep_str ++ "htmlout" ++ std.fs.path.sep_str;
|
||||
const emccOutputFile = "index.html";
|
||||
pub fn emscriptenRunStep(b: *std.Build) !*std.Build.Step.Run {
|
||||
// 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, b.sysroot.?.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}",
|
||||
.{ emrunExe }
|
||||
);
|
||||
} else {
|
||||
emrun_run_arg = try std.fmt.bufPrint(
|
||||
emrun_run_arg,
|
||||
"{s}" ++ std.fs.path.sep_str ++ "{s}",
|
||||
.{ b.sysroot.?, emrunExe }
|
||||
);
|
||||
}
|
||||
|
||||
const run_cmd = b.addSystemCommand(&[_][]const u8{ emrun_run_arg, emccOutputDir ++ emccOutputFile });
|
||||
return run_cmd;
|
||||
}
|
||||
|
||||
// Creates the static library to build a project for Emscripten.
|
||||
pub fn compileForEmscripten(
|
||||
b: *std.Build,
|
||||
name: []const u8,
|
||||
root_source_file: []const u8,
|
||||
target: std.Build.ResolvedTarget,
|
||||
optimize: std.builtin.Mode,
|
||||
) !*std.Build.Step.Compile {
|
||||
// TODO: It might be a good idea to create a custom compile step, that does
|
||||
// both the compile to static library and the link with emcc by overidding
|
||||
// the make function of the step. However it might also be a bad idea since
|
||||
// it messes with the build system itself.
|
||||
|
||||
// The project is built as a library and linked later.
|
||||
const lib = b.addStaticLibrary(.{
|
||||
.name = name,
|
||||
.root_source_file = b.path(root_source_file),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const emscripten_headers = try std.fs.path.join(b.allocator, &.{ b.sysroot.?, "cache", "sysroot", "include" });
|
||||
defer b.allocator.free(emscripten_headers);
|
||||
lib.addIncludePath(.{ .cwd_relative = emscripten_headers });
|
||||
return lib;
|
||||
}
|
||||
|
||||
// Links a set of items together using emscripten.
|
||||
//
|
||||
// Will accept objects and static libraries as items to link. As for files to
|
||||
// include, it is recomended to have a single resources directory and just pass
|
||||
// the entire directory instead of passing every file individually. The entire
|
||||
// path given will be the path to read the file within the program. So, if
|
||||
// "resources/image.png" is passed, your program will use "resources/image.png"
|
||||
// as the path to load the file.
|
||||
//
|
||||
// TODO: Test if shared libraries are accepted, I don't remember if emcc can
|
||||
// link a shared library with a project or not.
|
||||
// TODO: Add a parameter that allows a custom output directory.
|
||||
pub fn linkWithEmscripten(
|
||||
b: *std.Build,
|
||||
itemsToLink: []const *std.Build.Step.Compile,
|
||||
) !*std.Build.Step.Run {
|
||||
const emccExe = switch (builtin.os.tag) {
|
||||
.windows => "emcc.bat",
|
||||
else => "emcc",
|
||||
};
|
||||
var emcc_run_arg = try b.allocator.alloc(u8, b.sysroot.?.len + emccExe.len + 1);
|
||||
defer b.allocator.free(emcc_run_arg);
|
||||
|
||||
if (b.sysroot == null) {
|
||||
emcc_run_arg = try std.fmt.bufPrint(
|
||||
emcc_run_arg,
|
||||
"{s}",
|
||||
.{ emccExe }
|
||||
);
|
||||
} else {
|
||||
emcc_run_arg = try std.fmt.bufPrint(
|
||||
emcc_run_arg,
|
||||
"{s}" ++ std.fs.path.sep_str ++ "{s}",
|
||||
.{ b.sysroot.?, emccExe },
|
||||
);
|
||||
}
|
||||
|
||||
// Create the output directory because emcc can't do it.
|
||||
const mkdir_command = switch (builtin.os.tag) {
|
||||
.windows => b.addSystemCommand(&.{ "cmd.exe", "/c", "if", "not", "exist", emccOutputDir, "mkdir", emccOutputDir }),
|
||||
else => b.addSystemCommand(&.{ "mkdir", "-p", emccOutputDir }),
|
||||
};
|
||||
|
||||
// Actually link everything together.
|
||||
const emcc_command = b.addSystemCommand(&[_][]const u8{emcc_run_arg});
|
||||
|
||||
for (itemsToLink) |item| {
|
||||
emcc_command.addFileArg(item.getEmittedBin());
|
||||
emcc_command.step.dependOn(&item.step);
|
||||
}
|
||||
// This puts the file in zig-out/htmlout/index.html.
|
||||
emcc_command.step.dependOn(&mkdir_command.step);
|
||||
emcc_command.addArgs(&[_][]const u8{
|
||||
"-o",
|
||||
emccOutputDir ++ emccOutputFile,
|
||||
"-sUSE_OFFSET_CONVERTER",
|
||||
"-sFULL-ES3=1",
|
||||
"-sUSE_GLFW=3",
|
||||
"-sASYNCIFY",
|
||||
"-O3",
|
||||
"--emrun",
|
||||
});
|
||||
return emcc_command;
|
||||
}
|
||||
|
||||
// TODO: See if zig's standard library already has somehing like this.
|
||||
fn lastIndexOf(string: []const u8, character: u8) usize {
|
||||
// Interestingly, Zig has no nice way of iterating a slice backwards.
|
||||
for (0..string.len) |i| {
|
||||
const index = string.len - i - 1;
|
||||
if (string[index] == character) return index;
|
||||
}
|
||||
return string.len - 1;
|
||||
}
|
||||
@ -13,7 +13,7 @@ const CircleWave = struct {
|
||||
const screenWidth = 800;
|
||||
const screenHeight = 450;
|
||||
|
||||
const colors = [14]rl.Color{ rl.Color.orange, rl.Color.red, rl.Color.gold, rl.Color.lime, rl.Color.blue, rl.Color.violet, rl.Color.brown, rl.Color.light_gray, rl.Color.pink, rl.Color.yellow, rl.Color.green, rl.Color.sky_blue, rl.Color.purple, rl.Color.beige };
|
||||
const colors = [14]rl.Color{ .orange, .red, .gold, .lime, .blue, .violet, .brown, .light_gray, .pink, .yellow, .green, .sky_blue, .purple, .beige };
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
@ -57,14 +57,14 @@ pub fn main() !void {
|
||||
rl.updateMusicStream(music); // Update music buffer with new stream data
|
||||
|
||||
// Restart music playing (stop and play)
|
||||
if (rl.isKeyPressed(rl.KeyboardKey.space)) {
|
||||
if (rl.isKeyPressed(.space)) {
|
||||
rl.stopMusicStream(music);
|
||||
rl.playMusicStream(music);
|
||||
pause = false;
|
||||
}
|
||||
|
||||
// Pause/Resume music playing
|
||||
if (rl.isKeyPressed(rl.KeyboardKey.p)) {
|
||||
if (rl.isKeyPressed(.p)) {
|
||||
pause = !pause;
|
||||
|
||||
if (pause) {
|
||||
@ -74,9 +74,9 @@ pub fn main() !void {
|
||||
}
|
||||
}
|
||||
|
||||
if (rl.isKeyDown(rl.KeyboardKey.down)) {
|
||||
if (rl.isKeyDown(.down)) {
|
||||
pitch -= 0.01;
|
||||
} else if (rl.isKeyDown(rl.KeyboardKey.up)) {
|
||||
} else if (rl.isKeyDown(.up)) {
|
||||
pitch += 0.01;
|
||||
}
|
||||
|
||||
@ -103,24 +103,24 @@ pub fn main() !void {
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.white);
|
||||
rl.clearBackground(.white);
|
||||
|
||||
for (circles) |circle| {
|
||||
rl.drawCircleV(circle.position, circle.radius, rl.fade(circle.color, circle.alpha));
|
||||
rl.drawCircleV(circle.position, circle.radius, .fade(circle.color, circle.alpha));
|
||||
}
|
||||
|
||||
// Draw time bar
|
||||
rl.drawRectangle(20, screenHeight - 20 - 12, screenWidth - 40, 12, rl.Color.light_gray);
|
||||
rl.drawRectangle(20, screenHeight - 20 - 12, @intFromFloat(timePlayed), 12, rl.Color.maroon);
|
||||
rl.drawRectangleLines(20, screenHeight - 20 - 12, screenWidth - 40, 12, rl.Color.gray);
|
||||
rl.drawRectangle(20, screenHeight - 20 - 12, screenWidth - 40, 12, .light_gray);
|
||||
rl.drawRectangle(20, screenHeight - 20 - 12, @intFromFloat(timePlayed), 12, .maroon);
|
||||
rl.drawRectangleLines(20, screenHeight - 20 - 12, screenWidth - 40, 12, .gray);
|
||||
|
||||
// Draw help instructions
|
||||
rl.drawRectangle(20, 20, 425, 145, rl.Color.white);
|
||||
rl.drawRectangleLines(20, 20, 425, 145, rl.Color.gray);
|
||||
rl.drawText("PRESS SPACE TO RESTART MUSIC", 40, 40, 20, rl.Color.black);
|
||||
rl.drawText("PRESS P TO PAUSE/RESUME", 40, 70, 20, rl.Color.black);
|
||||
rl.drawText("PRESS UP/DOWN TO CHANGE SPEED", 40, 100, 20, rl.Color.black);
|
||||
rl.drawText(rl.textFormat("SPEED: %f", .{pitch}), 40, 130, 20, rl.Color.maroon);
|
||||
rl.drawRectangle(20, 20, 425, 145, .white);
|
||||
rl.drawRectangleLines(20, 20, 425, 145, .gray);
|
||||
rl.drawText("PRESS SPACE TO RESTART MUSIC", 40, 40, 20, .black);
|
||||
rl.drawText("PRESS P TO PAUSE/RESUME", 40, 70, 20, .black);
|
||||
rl.drawText("PRESS UP/DOWN TO CHANGE SPEED", 40, 100, 20, .black);
|
||||
rl.drawText(rl.textFormat("SPEED: %f", .{pitch}), 40, 130, 20, .maroon);
|
||||
|
||||
rl.endDrawing();
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
@ -34,13 +34,13 @@ pub fn main() !void {
|
||||
rl.updateMusicStream(music); // Update music buffer with new stream data
|
||||
|
||||
// Restart music playing (stop and play)
|
||||
if (rl.isKeyPressed(rl.KeyboardKey.space)) {
|
||||
if (rl.isKeyPressed(.space)) {
|
||||
rl.stopMusicStream(music);
|
||||
rl.playMusicStream(music);
|
||||
}
|
||||
|
||||
// Pause/Resume music playing
|
||||
if (rl.isKeyPressed(rl.KeyboardKey.p)) {
|
||||
if (rl.isKeyPressed(.p)) {
|
||||
pause = !pause;
|
||||
|
||||
if (pause) {
|
||||
@ -63,16 +63,16 @@ pub fn main() !void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.white);
|
||||
rl.clearBackground(.white);
|
||||
|
||||
rl.drawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, rl.Color.light_gray);
|
||||
rl.drawText("MUSIC SHOULD BE PLAYING!", 255, 150, 20, .light_gray);
|
||||
|
||||
rl.drawRectangle(200, 200, 400, 12, rl.Color.light_gray);
|
||||
rl.drawRectangle(200, 200, @intFromFloat(timePlayed * 400), 12, rl.Color.maroon);
|
||||
rl.drawRectangleLines(200, 200, 400, 12, rl.Color.gray);
|
||||
rl.drawRectangle(200, 200, 400, 12, .light_gray);
|
||||
rl.drawRectangle(200, 200, @intFromFloat(timePlayed * 400), 12, .maroon);
|
||||
rl.drawRectangleLines(200, 200, 400, 12, .gray);
|
||||
|
||||
rl.drawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, rl.Color.light_gray);
|
||||
rl.drawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, rl.Color.light_gray);
|
||||
rl.drawText("PRESS SPACE TO RESTART MUSIC", 215, 250, 20, .light_gray);
|
||||
rl.drawText("PRESS P TO PAUSE/RESUME MUSIC", 208, 280, 20, .light_gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,17 +1,20 @@
|
||||
// raylib-zig (c) Nikolas Wipper 2023
|
||||
|
||||
const rl = @import("raylib");
|
||||
const std = @import("std");
|
||||
|
||||
const MAX_SAMPLES = 512;
|
||||
const MAX_SAMPLES_PER_UPDATE = 4096;
|
||||
|
||||
const pi = @import("std").math.pi;
|
||||
const C = std.builtin.CallingConvention.c;
|
||||
|
||||
var frequency: f32 = 440;
|
||||
var audioFrequency: f32 = 440;
|
||||
var oldFrequency: f32 = 1;
|
||||
var sineIdx: f32 = 0;
|
||||
|
||||
fn audioInputCallback(buffer: ?*anyopaque, frames: c_uint) callconv(.C) void {
|
||||
fn audioInputCallback(buffer: ?*anyopaque, frames: c_uint) callconv(C) void {
|
||||
audioFrequency = frequency + (audioFrequency - frequency) * 0.95;
|
||||
|
||||
const incr = audioFrequency / 44100;
|
||||
@ -111,12 +114,12 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawText(rl.textFormat("sine frequency: %i", .{@as(i32, @intFromFloat(frequency))}),
|
||||
rl.getScreenWidth() - 220, 10, 20, rl.Color.red);
|
||||
rl.getScreenWidth() - 220, 10, 20, .red);
|
||||
rl.drawText("click mouse button to change frequency or pan",
|
||||
10, 10, 20, rl.Color.dark_gray);
|
||||
10, 10, 20, .dark_gray);
|
||||
|
||||
// Draw the current buffer state proportionate to the screen
|
||||
for (0..screenWidth) |i| {
|
||||
@ -124,7 +127,7 @@ pub fn main() anyerror!void {
|
||||
const y: f32 = @floatFromInt(data[@divFloor(i * MAX_SAMPLES, screenWidth)]);
|
||||
position.y = 250 + 50 * y / 32000;
|
||||
|
||||
rl.drawPixelV(position, rl.Color.red);
|
||||
rl.drawPixelV(position, .red);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
@ -28,8 +28,8 @@ pub fn main() !void {
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (rl.isKeyPressed(rl.KeyboardKey.space)) rl.playSound(fxWav); // Play WAV sound
|
||||
if (rl.isKeyPressed(rl.KeyboardKey.enter)) rl.playSound(fxOgg); // Play OGG sound
|
||||
if (rl.isKeyPressed(.space)) rl.playSound(fxWav); // Play WAV sound
|
||||
if (rl.isKeyPressed(.enter)) rl.playSound(fxOgg); // Play OGG sound
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
@ -37,10 +37,10 @@ pub fn main() !void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.white);
|
||||
rl.clearBackground(.white);
|
||||
|
||||
rl.drawText("Press SPACE to PLAY the WAV sound!", 200, 180, 20, rl.Color.light_gray);
|
||||
rl.drawText("Press ENTER to PLAY the OGG sound!", 200, 220, 20, rl.Color.light_gray);
|
||||
rl.drawText("Press SPACE to PLAY the WAV sound!", 200, 180, 20, .light_gray);
|
||||
rl.drawText("Press ENTER to PLAY the OGG sound!", 200, 220, 20, .light_gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -27,7 +27,7 @@ pub fn main() anyerror!void {
|
||||
|
||||
spacing += @as(i32, @intFromFloat(buildings[i].width));
|
||||
|
||||
buildColors[i] = rl.Color.init(
|
||||
buildColors[i] = .init(
|
||||
@as(u8, @intCast(rl.getRandomValue(200, 240))),
|
||||
@as(u8, @intCast(rl.getRandomValue(200, 240))),
|
||||
@as(u8, @intCast(rl.getRandomValue(200, 250))),
|
||||
@ -36,8 +36,8 @@ pub fn main() anyerror!void {
|
||||
}
|
||||
|
||||
var camera = rl.Camera2D{
|
||||
.target = rl.Vector2.init(player.x + 20, player.y + 20),
|
||||
.offset = rl.Vector2.init(screenWidth / 2, screenHeight / 2),
|
||||
.target = .init(player.x + 20, player.y + 20),
|
||||
.offset = .init(screenWidth / 2, screenHeight / 2),
|
||||
.rotation = 0,
|
||||
.zoom = 1,
|
||||
};
|
||||
@ -58,7 +58,7 @@ pub fn main() anyerror!void {
|
||||
}
|
||||
|
||||
// Camera target follows player
|
||||
camera.target = rl.Vector2.init(player.x + 20, player.y + 20);
|
||||
camera.target = .init(player.x + 20, player.y + 20);
|
||||
|
||||
// Camera rotation controls
|
||||
if (rl.isKeyDown(.a)) {
|
||||
@ -87,51 +87,51 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
{
|
||||
camera.begin();
|
||||
defer camera.end();
|
||||
|
||||
rl.drawRectangle(-6000, 320, 13000, 8000, rl.Color.dark_gray);
|
||||
rl.drawRectangle(-6000, 320, 13000, 8000, .dark_gray);
|
||||
|
||||
for (buildings, 0..) |building, i| {
|
||||
rl.drawRectangleRec(building, buildColors[i]);
|
||||
}
|
||||
|
||||
rl.drawRectangleRec(player, rl.Color.red);
|
||||
rl.drawRectangleRec(player, .red);
|
||||
|
||||
rl.drawLine(
|
||||
@as(i32, @intFromFloat(camera.target.x)),
|
||||
-screenHeight * 10,
|
||||
@as(i32, @intFromFloat(camera.target.x)),
|
||||
screenHeight * 10,
|
||||
rl.Color.green,
|
||||
.green,
|
||||
);
|
||||
rl.drawLine(
|
||||
-screenWidth * 10,
|
||||
@as(i32, @intFromFloat(camera.target.y)),
|
||||
screenWidth * 10,
|
||||
@as(i32, @intFromFloat(camera.target.y)),
|
||||
rl.Color.green,
|
||||
.green,
|
||||
);
|
||||
}
|
||||
|
||||
rl.drawText("SCREEN AREA", 640, 10, 20, rl.Color.red);
|
||||
rl.drawText("SCREEN AREA", 640, 10, 20, .red);
|
||||
|
||||
rl.drawRectangle(0, 0, screenWidth, 5, rl.Color.red);
|
||||
rl.drawRectangle(0, 5, 5, screenHeight - 10, rl.Color.red);
|
||||
rl.drawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, rl.Color.red);
|
||||
rl.drawRectangle(0, screenHeight - 5, screenWidth, 5, rl.Color.red);
|
||||
rl.drawRectangle(0, 0, screenWidth, 5, .red);
|
||||
rl.drawRectangle(0, 5, 5, screenHeight - 10, .red);
|
||||
rl.drawRectangle(screenWidth - 5, 5, 5, screenHeight - 10, .red);
|
||||
rl.drawRectangle(0, screenHeight - 5, screenWidth, 5, .red);
|
||||
|
||||
rl.drawRectangle(10, 10, 250, 113, rl.Color.sky_blue.fade(0.5));
|
||||
rl.drawRectangleLines(10, 10, 250, 113, rl.Color.blue);
|
||||
rl.drawRectangle(10, 10, 250, 113, .fade(.sky_blue, 0.5));
|
||||
rl.drawRectangleLines(10, 10, 250, 113, .blue);
|
||||
|
||||
rl.drawText("Free 2d camera controls:", 20, 20, 10, rl.Color.black);
|
||||
rl.drawText("- Right/Left to move Offset", 40, 40, 10, rl.Color.dark_gray);
|
||||
rl.drawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, rl.Color.dark_gray);
|
||||
rl.drawText("- A / S to Rotate", 40, 80, 10, rl.Color.dark_gray);
|
||||
rl.drawText("- R to reset Zoom and Rotation", 40, 100, 10, rl.Color.dark_gray);
|
||||
rl.drawText("Free 2d camera controls:", 20, 20, 10, .black);
|
||||
rl.drawText("- Right/Left to move Offset", 40, 40, 10, .dark_gray);
|
||||
rl.drawText("- Mouse Wheel to Zoom in-out", 40, 60, 10, .dark_gray);
|
||||
rl.drawText("- A / S to Rotate", 40, 80, 10, .dark_gray);
|
||||
rl.drawText("- R to reset Zoom and Rotation", 40, 100, 10, .dark_gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -91,7 +91,7 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
{
|
||||
camera.begin();
|
||||
@ -103,14 +103,14 @@ pub fn main() anyerror!void {
|
||||
rl.drawGrid(100, 50);
|
||||
rl.gl.rlPopMatrix();
|
||||
|
||||
rl.drawCircle(screenWidth / 2, screenHeight / 2, 50, rl.Color.maroon);
|
||||
rl.drawCircle(screenWidth / 2, screenHeight / 2, 50, .maroon);
|
||||
}
|
||||
|
||||
rl.drawText("[1][2] Select mouse zoom mode (Wheel or Move)", 20, 20, 20, rl.Color.dark_gray);
|
||||
rl.drawText("[1][2] Select mouse zoom mode (Wheel or Move)", 20, 20, 20, .dark_gray);
|
||||
if (zoomMode == 0) {
|
||||
rl.drawText("Mouse right button drag to move, mouse wheel to zoom", 20, 50, 20, rl.Color.dark_gray);
|
||||
rl.drawText("Mouse right button drag to move, mouse wheel to zoom", 20, 50, 20, .dark_gray);
|
||||
} else {
|
||||
rl.drawText("Mouse right button drag to move, mouse press and move to zoom", 20, 50, 20, rl.Color.dark_gray);
|
||||
rl.drawText("Mouse right button drag to move, mouse press and move to zoom", 20, 50, 20, .dark_gray);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
334
examples/core/2d_camera_platformer.zig
Normal file
@ -0,0 +1,334 @@
|
||||
// raylib-zig (c) Axel Magnuson 2025
|
||||
//
|
||||
// This is a fairly close 1-1 copy of the original example from raylib, and
|
||||
// thus might not represent completely idiomatic or clean zig.
|
||||
|
||||
const rl = @import("raylib");
|
||||
const rm = @import("raymath");
|
||||
|
||||
const Rect = rl.Rectangle;
|
||||
const Vec2 = rl.Vector2;
|
||||
const Color = rl.Color;
|
||||
const Camera2D = rl.Camera2D;
|
||||
|
||||
const CameraUpdater = *const fn (
|
||||
camera: *Camera2D,
|
||||
player: *Player,
|
||||
env_items: []EnvItem,
|
||||
delta: f32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) void;
|
||||
|
||||
const G: i32 = 400;
|
||||
const PLAYER_JUMP_SPD: f32 = 350;
|
||||
const PLAYER_HOR_SPD: f32 = 200;
|
||||
|
||||
const Player = struct {
|
||||
can_jump: bool,
|
||||
speed: f32,
|
||||
position: rl.Vector2,
|
||||
};
|
||||
|
||||
const EnvItem = struct {
|
||||
blocking: bool,
|
||||
rect: rl.Rectangle,
|
||||
color: rl.Color,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.initWindow(screen_width, screen_height, "raylib [core] example - 2d camera");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
var player: Player = .{ .can_jump = false, .speed = 0, .position = Vec2.init(400, 280) };
|
||||
var env_items = [_]EnvItem{
|
||||
.{ .rect = Rect.init(0, 0, 1000, 400), .blocking = false, .color = .light_gray },
|
||||
.{ .rect = Rect.init(0, 400, 1000, 200), .blocking = true, .color = .gray },
|
||||
.{ .rect = Rect.init(300, 200, 400, 10), .blocking = true, .color = .gray },
|
||||
.{ .rect = Rect.init(250, 300, 100, 10), .blocking = true, .color = .gray },
|
||||
.{ .rect = Rect.init(650, 300, 100, 10), .blocking = true, .color = .gray },
|
||||
};
|
||||
|
||||
var camera: rl.Camera2D = .{
|
||||
.target = player.position,
|
||||
.offset = Vec2.init(screen_width / 2, screen_height / 2),
|
||||
.rotation = 0,
|
||||
.zoom = 1,
|
||||
};
|
||||
|
||||
// store pointers to the multiple functions that could be used to update the camera
|
||||
const camera_updaters = [_]CameraUpdater{
|
||||
updateCameraCenter,
|
||||
updatecameraCenterInsideMap,
|
||||
updateCameraCenterSmoothFollow,
|
||||
updateCameraEvenOutOnLanding,
|
||||
updateCameraPlayerBoundsPush,
|
||||
};
|
||||
|
||||
var camera_option: usize = 0;
|
||||
|
||||
const camera_descriptions = [_][:0]const u8{
|
||||
"Follow player center",
|
||||
"Follow player center, but clamp to map edges",
|
||||
"Follow player center; smoothed",
|
||||
"Follow player center horizontally; update player center vertically after landing",
|
||||
"Player push camera on getting too close to screen edge",
|
||||
};
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames per second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) {
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
const delta_time = rl.getFrameTime();
|
||||
|
||||
updatePlayer(&player, &env_items, delta_time);
|
||||
|
||||
camera.zoom += rl.getMouseWheelMove() * 0.05;
|
||||
if (camera.zoom > 3) camera.zoom = 3;
|
||||
if (camera.zoom < 0.25) camera.zoom = 0.25;
|
||||
|
||||
// input: reset
|
||||
if (rl.isKeyPressed(.r)) {
|
||||
camera.zoom = 1;
|
||||
player.position = Vec2.init(400, 280);
|
||||
}
|
||||
|
||||
// input: cycle camera mode
|
||||
if (rl.isKeyPressed(.c)) {
|
||||
camera_option = (camera_option + 1) % camera_updaters.len;
|
||||
}
|
||||
|
||||
// call update camera by pointer
|
||||
camera_updaters[camera_option](
|
||||
&camera,
|
||||
&player,
|
||||
&env_items,
|
||||
delta_time,
|
||||
screen_width,
|
||||
screen_height,
|
||||
);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
{
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.light_gray);
|
||||
|
||||
{
|
||||
rl.beginMode2D(camera);
|
||||
defer rl.endMode2D();
|
||||
|
||||
for (env_items) |env_item| {
|
||||
rl.drawRectangleRec(env_item.rect, env_item.color);
|
||||
}
|
||||
|
||||
const player_rect = Rect.init(player.position.x - 20, player.position.y - 40, 40, 40);
|
||||
rl.drawRectangleRec(player_rect, .red);
|
||||
rl.drawCircleV(player.position, 5, .gold);
|
||||
}
|
||||
|
||||
rl.drawText("Controls:", 20, 20, 10, .black);
|
||||
rl.drawText("- Right/Left to move", 40, 40, 10, .dark_gray);
|
||||
// todo: controls text
|
||||
rl.drawText("- Current camera mode:", 20, 120, 10, .black);
|
||||
rl.drawText(camera_descriptions[camera_option], 40, 140, 10, .dark_gray);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Player update function
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
fn updatePlayer(player: *Player, env_items: []EnvItem, delta: f32) void {
|
||||
if (rl.isKeyDown(.left)) player.position.x -= PLAYER_HOR_SPD * delta;
|
||||
if (rl.isKeyDown(.right)) player.position.x += PLAYER_HOR_SPD * delta;
|
||||
if (rl.isKeyDown(.space) and player.can_jump) {
|
||||
player.speed = -PLAYER_JUMP_SPD;
|
||||
player.can_jump = false;
|
||||
}
|
||||
|
||||
var hit_obstacle = false;
|
||||
for (env_items) |ei| {
|
||||
var p: *Vec2 = &player.position;
|
||||
if (ei.blocking and
|
||||
ei.rect.x <= p.x and
|
||||
ei.rect.x + ei.rect.width >= p.x and
|
||||
ei.rect.y >= p.y and
|
||||
ei.rect.y <= p.y + player.speed * delta)
|
||||
{
|
||||
hit_obstacle = true;
|
||||
player.speed = 0;
|
||||
p.y = ei.rect.y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hit_obstacle) {
|
||||
player.position.y += player.speed * delta;
|
||||
player.speed += G * delta;
|
||||
player.can_jump = false;
|
||||
} else player.can_jump = true;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Selectable camera update functions
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
// Follow player center
|
||||
fn updateCameraCenter(
|
||||
camera: *Camera2D,
|
||||
player: *Player,
|
||||
_: []EnvItem,
|
||||
_: f32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) void {
|
||||
const widthf: f32 = @floatFromInt(width);
|
||||
const heightf: f32 = @floatFromInt(height);
|
||||
camera.offset = Vec2.init(widthf / 2, heightf / 2);
|
||||
camera.target = player.position;
|
||||
}
|
||||
|
||||
// Follow player center, but clamp to map edges
|
||||
fn updatecameraCenterInsideMap(
|
||||
camera: *Camera2D,
|
||||
player: *Player,
|
||||
env_items: []EnvItem,
|
||||
_: f32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) void {
|
||||
const widthf: f32 = @floatFromInt(width);
|
||||
const heightf: f32 = @floatFromInt(height);
|
||||
camera.offset = Vec2.init(widthf / 2, heightf / 2);
|
||||
camera.target = player.position;
|
||||
|
||||
var min_x: f32 = 1000;
|
||||
var min_y: f32 = 1000;
|
||||
var max_x: f32 = -1000;
|
||||
var max_y: f32 = -1000;
|
||||
|
||||
for (env_items) |ei| {
|
||||
min_x = @min(ei.rect.x, min_x);
|
||||
min_y = @min(ei.rect.y, min_y);
|
||||
max_x = @max(ei.rect.x + ei.rect.width, max_x);
|
||||
max_y = @max(ei.rect.y + ei.rect.height, max_y);
|
||||
}
|
||||
|
||||
const max = rl.getWorldToScreen2D(Vec2.init(max_x, max_y), camera.*);
|
||||
const min = rl.getWorldToScreen2D(Vec2.init(min_x, min_y), camera.*);
|
||||
|
||||
if (max.x < widthf) camera.offset.x = widthf - (max.x - widthf / 2);
|
||||
if (max.y < heightf) camera.offset.y = heightf - (max.y - heightf / 2);
|
||||
if (min.x > 0) camera.offset.x = widthf / 2 - min.x;
|
||||
if (min.y > 0) camera.offset.y = heightf / 2 - min.y;
|
||||
}
|
||||
|
||||
// Follow player center; smoothed
|
||||
fn updateCameraCenterSmoothFollow(
|
||||
camera: *Camera2D,
|
||||
player: *Player,
|
||||
_: []EnvItem,
|
||||
delta: f32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) void {
|
||||
const min_speed = 30;
|
||||
const min_effect_length = 10;
|
||||
const fraction_speed = 0.8;
|
||||
|
||||
const widthf: f32 = @floatFromInt(width);
|
||||
const heightf: f32 = @floatFromInt(height);
|
||||
|
||||
camera.offset = Vec2.init(widthf / 2, heightf / 2);
|
||||
const diff = player.position.subtract(camera.target);
|
||||
const length = diff.length();
|
||||
|
||||
if (length > min_effect_length) {
|
||||
const speed = @max(fraction_speed * length, min_speed);
|
||||
camera.target = camera.target.add(diff.scale(speed * delta / length));
|
||||
}
|
||||
}
|
||||
|
||||
var evening_out: bool = false;
|
||||
var even_out_target: f32 = 0;
|
||||
|
||||
// Follow player center horizontally; update player center vertically after landing
|
||||
fn updateCameraEvenOutOnLanding(
|
||||
camera: *Camera2D,
|
||||
player: *Player,
|
||||
_: []EnvItem,
|
||||
delta: f32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) void {
|
||||
const even_out_speed = 700;
|
||||
|
||||
const widthf: f32 = @floatFromInt(width);
|
||||
const heightf: f32 = @floatFromInt(height);
|
||||
|
||||
camera.offset = Vec2.init(widthf / 2, heightf / 2);
|
||||
camera.target.x = player.position.x;
|
||||
|
||||
if (evening_out) {
|
||||
if (even_out_target > camera.target.y) {
|
||||
camera.target.y += even_out_speed * delta;
|
||||
if (camera.target.y > even_out_target) {
|
||||
camera.target.y = even_out_target;
|
||||
evening_out = false;
|
||||
}
|
||||
} else {
|
||||
camera.target.y -= even_out_speed * delta;
|
||||
if (camera.target.y < even_out_target) {
|
||||
camera.target.y = even_out_target;
|
||||
evening_out = false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (player.can_jump and player.speed == 0 and player.position.y != camera.target.y) {
|
||||
evening_out = true;
|
||||
even_out_target = player.position.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Player push camera on getting too close to screen edge
|
||||
fn updateCameraPlayerBoundsPush(
|
||||
camera: *Camera2D,
|
||||
player: *Player,
|
||||
_: []EnvItem,
|
||||
_: f32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
) void {
|
||||
const bbox = Vec2.init(0.2, 0.2);
|
||||
|
||||
const widthf: f32 = @floatFromInt(width);
|
||||
const heightf: f32 = @floatFromInt(height);
|
||||
|
||||
const bbox_world_min = rl.getScreenToWorld2D(Vec2.init((1 - bbox.x) * 0.5 * widthf, (1 - bbox.y) * 0.5 * heightf), camera.*);
|
||||
const bbox_world_max = rl.getScreenToWorld2D(Vec2.init((1 + bbox.x) * 0.5 * widthf, (1 + bbox.y) * 0.5 * heightf), camera.*);
|
||||
camera.offset = Vec2.init((1 - bbox.x) * 0.5 * widthf, (1 - bbox.y) * 0.5 * heightf);
|
||||
|
||||
if (player.position.x < bbox_world_min.x) camera.target.x = player.position.x;
|
||||
if (player.position.y < bbox_world_min.y) camera.target.y = player.position.y;
|
||||
if (player.position.x > bbox_world_max.x) camera.target.x = bbox_world_min.x + (player.position.x - bbox_world_max.x);
|
||||
if (player.position.y > bbox_world_max.y) camera.target.y = bbox_world_min.y + (player.position.y - bbox_world_max.y);
|
||||
}
|
||||
@ -14,9 +14,9 @@ pub fn main() anyerror!void {
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
var camera = rl.Camera3D{
|
||||
.position = rl.Vector3.init(4, 2, 4),
|
||||
.target = rl.Vector3.init(0, 1.8, 0),
|
||||
.up = rl.Vector3.init(0, 1, 0),
|
||||
.position = .init(4, 2, 4),
|
||||
.target = .init(0, 1.8, 0),
|
||||
.up = .init(0, 1, 0),
|
||||
.fovy = 60,
|
||||
.projection = .perspective,
|
||||
};
|
||||
@ -27,12 +27,12 @@ pub fn main() anyerror!void {
|
||||
|
||||
for (0..heights.len) |i| {
|
||||
heights[i] = @as(f32, @floatFromInt(rl.getRandomValue(1, 12)));
|
||||
positions[i] = rl.Vector3.init(
|
||||
positions[i] = .init(
|
||||
@as(f32, @floatFromInt(rl.getRandomValue(-15, 15))),
|
||||
heights[i] / 2.0,
|
||||
@as(f32, @floatFromInt(rl.getRandomValue(-15, 15))),
|
||||
);
|
||||
colors[i] = rl.Color.init(
|
||||
colors[i] = .init(
|
||||
@as(u8, @intCast(rl.getRandomValue(20, 255))),
|
||||
@as(u8, @intCast(rl.getRandomValue(10, 55))),
|
||||
30,
|
||||
@ -56,31 +56,31 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
{
|
||||
camera.begin();
|
||||
defer camera.end();
|
||||
|
||||
// Draw ground
|
||||
rl.drawPlane(rl.Vector3.init(0, 0, 0), rl.Vector2.init(32, 32), rl.Color.light_gray);
|
||||
rl.drawCube(rl.Vector3.init(-16.0, 2.5, 0.0), 1.0, 5.0, 32.0, rl.Color.blue); // Draw a blue wall
|
||||
rl.drawCube(rl.Vector3.init(16.0, 2.5, 0.0), 1.0, 5.0, 32.0, rl.Color.lime); // Draw a green wall
|
||||
rl.drawCube(rl.Vector3.init(0.0, 2.5, 16.0), 32.0, 5.0, 1.0, rl.Color.gold); // Draw a yellow wall
|
||||
rl.drawPlane(.init(0, 0, 0), .init(32, 32), .light_gray);
|
||||
rl.drawCube(.init(-16.0, 2.5, 0.0), 1.0, 5.0, 32.0, .blue); // Draw a blue wall
|
||||
rl.drawCube(.init(16.0, 2.5, 0.0), 1.0, 5.0, 32.0, .lime); // Draw a green wall
|
||||
rl.drawCube(.init(0.0, 2.5, 16.0), 32.0, 5.0, 1.0, .gold); // Draw a yellow wall
|
||||
|
||||
// Draw some cubes around
|
||||
for (heights, 0..) |height, i| {
|
||||
rl.drawCube(positions[i], 2.0, height, 2.0, colors[i]);
|
||||
rl.drawCubeWires(positions[i], 2.0, height, 2.0, rl.Color.maroon);
|
||||
rl.drawCubeWires(positions[i], 2.0, height, 2.0, .maroon);
|
||||
}
|
||||
}
|
||||
|
||||
rl.drawRectangle(10, 10, 220, 70, rl.Color.sky_blue.fade(0.5));
|
||||
rl.drawRectangleLines(10, 10, 220, 70, rl.Color.blue);
|
||||
rl.drawRectangle(10, 10, 220, 70, .fade(.sky_blue, 0.5));
|
||||
rl.drawRectangleLines(10, 10, 220, 70, .blue);
|
||||
|
||||
rl.drawText("First person camera default controls:", 20, 20, 10, rl.Color.black);
|
||||
rl.drawText("- Move with keys: W, A, S, D", 40, 40, 10, rl.Color.dark_gray);
|
||||
rl.drawText("- Mouse move to look around", 40, 60, 10, rl.Color.dark_gray);
|
||||
rl.drawText("First person camera default controls:", 20, 20, 10, .black);
|
||||
rl.drawText("- Move with keys: W, A, S, D", 40, 40, 10, .dark_gray);
|
||||
rl.drawText("- Mouse move to look around", 40, 60, 10, .dark_gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,9 +16,9 @@ pub fn main() anyerror!void {
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
var camera = rl.Camera{
|
||||
.position = rl.Vector3.init(10, 10, 10),
|
||||
.target = rl.Vector3.init(0, 0, 0),
|
||||
.up = rl.Vector3.init(0, 1, 0),
|
||||
.position = .init(10, 10, 10),
|
||||
.target = .init(0, 0, 0),
|
||||
.up = .init(0, 1, 0),
|
||||
.fovy = 45,
|
||||
.projection = .perspective,
|
||||
};
|
||||
@ -36,7 +36,7 @@ pub fn main() anyerror!void {
|
||||
camera.update(.free);
|
||||
|
||||
if (rl.isKeyPressed(.z)) {
|
||||
camera.target = rl.Vector3.init(0, 0, 0);
|
||||
camera.target = .init(0, 0, 0);
|
||||
}
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
@ -45,25 +45,25 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
{
|
||||
camera.begin();
|
||||
defer camera.end();
|
||||
|
||||
rl.drawCube(cubePosition, 2, 2, 2, rl.Color.red);
|
||||
rl.drawCubeWires(cubePosition, 2, 2, 2, rl.Color.maroon);
|
||||
rl.drawCube(cubePosition, 2, 2, 2, .red);
|
||||
rl.drawCubeWires(cubePosition, 2, 2, 2, .maroon);
|
||||
|
||||
rl.drawGrid(10, 1);
|
||||
}
|
||||
|
||||
rl.drawRectangle(10, 10, 320, 93, rl.Color.fade(rl.Color.sky_blue, 0.5));
|
||||
rl.drawRectangleLines(10, 10, 320, 93, rl.Color.blue);
|
||||
rl.drawRectangle(10, 10, 320, 93, .fade(.sky_blue, 0.5));
|
||||
rl.drawRectangleLines(10, 10, 320, 93, .blue);
|
||||
|
||||
rl.drawText("Free camera default controls:", 20, 20, 10, rl.Color.black);
|
||||
rl.drawText("- Mouse Wheel to Zoom in-out", 40, 40, 10, rl.Color.dark_gray);
|
||||
rl.drawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, rl.Color.dark_gray);
|
||||
rl.drawText("- Z to zoom to (0, 0, 0)", 40, 80, 10, rl.Color.dark_gray);
|
||||
rl.drawText("Free camera default controls:", 20, 20, 10, .black);
|
||||
rl.drawText("- Mouse Wheel to Zoom in-out", 40, 40, 10, .dark_gray);
|
||||
rl.drawText("- Mouse Wheel Pressed to Pan", 40, 60, 10, .dark_gray);
|
||||
rl.drawText("- Z to zoom to (0, 0, 0)", 40, 80, 10, .dark_gray);
|
||||
//-----------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,9 +11,9 @@ pub fn main() anyerror!void {
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
var camera = rl.Camera{
|
||||
.position = rl.Vector3.init(10, 10, 10),
|
||||
.target = rl.Vector3.init(0, 0, 0),
|
||||
.up = rl.Vector3.init(0, 1, 0),
|
||||
.position = .init(10, 10, 10),
|
||||
.target = .init(0, 0, 0),
|
||||
.up = .init(0, 1, 0),
|
||||
.fovy = 45,
|
||||
.projection = .perspective,
|
||||
};
|
||||
@ -44,8 +44,8 @@ pub fn main() anyerror!void {
|
||||
|
||||
// Check collision between ray and box
|
||||
collision = rl.getRayCollisionBox(ray, rl.BoundingBox{
|
||||
.max = rl.Vector3.init(cubePosition.x - cubeSize.x / 2, cubePosition.y - cubeSize.y / 2, cubePosition.z - cubeSize.z / 2),
|
||||
.min = rl.Vector3.init(cubePosition.x + cubeSize.x / 2, cubePosition.y + cubeSize.y / 2, cubePosition.z + cubeSize.z / 2),
|
||||
.max = .init(cubePosition.x - cubeSize.x / 2, cubePosition.y - cubeSize.y / 2, cubePosition.z - cubeSize.z / 2),
|
||||
.min = .init(cubePosition.x + cubeSize.x / 2, cubePosition.y + cubeSize.y / 2, cubePosition.z + cubeSize.z / 2),
|
||||
});
|
||||
} else collision.hit = false;
|
||||
}
|
||||
@ -56,33 +56,33 @@ pub fn main() anyerror!void {
|
||||
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
{
|
||||
camera.begin();
|
||||
defer camera.end();
|
||||
|
||||
if (collision.hit) {
|
||||
rl.drawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, rl.Color.red);
|
||||
rl.drawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, rl.Color.maroon);
|
||||
rl.drawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, .red);
|
||||
rl.drawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, .maroon);
|
||||
|
||||
rl.drawCubeWires(cubePosition, cubeSize.x + 0.2, cubeSize.y + 0.2, cubeSize.z + 0.2, rl.Color.green);
|
||||
rl.drawCubeWires(cubePosition, cubeSize.x + 0.2, cubeSize.y + 0.2, cubeSize.z + 0.2, .green);
|
||||
} else {
|
||||
rl.drawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, rl.Color.gray);
|
||||
rl.drawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, rl.Color.dark_gray);
|
||||
rl.drawCube(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, .gray);
|
||||
rl.drawCubeWires(cubePosition, cubeSize.x, cubeSize.y, cubeSize.z, .dark_gray);
|
||||
}
|
||||
|
||||
rl.drawRay(ray, rl.Color.maroon);
|
||||
rl.drawRay(ray, .maroon);
|
||||
rl.drawGrid(10, 1);
|
||||
}
|
||||
|
||||
rl.drawText("Try clicking on the box with your mouse!", 240, 10, 20, rl.Color.dark_gray);
|
||||
rl.drawText("Try clicking on the box with your mouse!", 240, 10, 20, .dark_gray);
|
||||
|
||||
if (collision.hit) {
|
||||
rl.drawText("BOX SELECTED", @divTrunc((screenWidth - rl.measureText("BOX SELECTED", 30)), 2), screenHeight * 0.1, 30, rl.Color.green);
|
||||
rl.drawText("BOX SELECTED", @divTrunc((screenWidth - rl.measureText("BOX SELECTED", 30)), 2), screenHeight * 0.1, 30, .green);
|
||||
}
|
||||
|
||||
rl.drawText("Right click mouse to toggle camera controls", 10, 430, 10, rl.Color.gray);
|
||||
rl.drawText("Right click mouse to toggle camera controls", 10, 430, 10, .gray);
|
||||
|
||||
rl.drawFPS(10, 10);
|
||||
}
|
||||
|
||||
@ -56,7 +56,7 @@ pub fn main() anyerror!void {
|
||||
// TODO: Update `title` state variables here!
|
||||
|
||||
// Press ENTER to change to `gameplay` state
|
||||
if (rl.isKeyPressed(.enter) or rl.isGestureDetected(.tap)) {
|
||||
if (rl.isKeyPressed(.enter) or rl.isGestureDetected(.{ .tap = true })) {
|
||||
current_screen = .gameplay;
|
||||
}
|
||||
},
|
||||
@ -64,7 +64,7 @@ pub fn main() anyerror!void {
|
||||
// TODO: Update `gameplay` state variables here!
|
||||
|
||||
// Press ENTER to change to `ending` state
|
||||
if (rl.isKeyPressed(.enter) or rl.isGestureDetected(.tap)) {
|
||||
if (rl.isKeyPressed(.enter) or rl.isGestureDetected(.{ .tap = true })) {
|
||||
current_screen = .ending;
|
||||
}
|
||||
},
|
||||
@ -72,7 +72,7 @@ pub fn main() anyerror!void {
|
||||
// TODO: Update `ending` state variables here!
|
||||
|
||||
// Press ENTER to return to `title` state
|
||||
if (rl.isKeyPressed(.enter) or rl.isGestureDetected(.tap)) {
|
||||
if (rl.isKeyPressed(.enter) or rl.isGestureDetected(.{ .tap = true })) {
|
||||
current_screen = .title;
|
||||
}
|
||||
},
|
||||
@ -85,18 +85,18 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
switch (current_screen) {
|
||||
.logo => {
|
||||
// TODO: Draw `logo` state here!
|
||||
rl.drawText("LOGO SCREEN", 20, 20, 40, rl.Color.light_gray);
|
||||
rl.drawText("LOGO SCREEN", 20, 20, 40, .light_gray);
|
||||
rl.drawText(
|
||||
"WAIT for 2 SECONDS...",
|
||||
290,
|
||||
220,
|
||||
20,
|
||||
rl.Color.gray,
|
||||
.gray,
|
||||
);
|
||||
},
|
||||
.title => {
|
||||
@ -106,21 +106,21 @@ pub fn main() anyerror!void {
|
||||
0,
|
||||
screen_width,
|
||||
screen_height,
|
||||
rl.Color.green,
|
||||
.green,
|
||||
);
|
||||
rl.drawText(
|
||||
"TITLE SCREEN",
|
||||
20,
|
||||
20,
|
||||
40,
|
||||
rl.Color.dark_green,
|
||||
.dark_green,
|
||||
);
|
||||
rl.drawText(
|
||||
"PRESS ENTER or TAP to JUMP to GAMEPLAY SCREEN",
|
||||
120,
|
||||
220,
|
||||
20,
|
||||
rl.Color.dark_green,
|
||||
.dark_green,
|
||||
);
|
||||
},
|
||||
.gameplay => {
|
||||
@ -130,15 +130,15 @@ pub fn main() anyerror!void {
|
||||
0,
|
||||
screen_width,
|
||||
screen_height,
|
||||
rl.Color.purple,
|
||||
.purple,
|
||||
);
|
||||
rl.drawText("GAMEPLAY SCREEN", 20, 20, 40, rl.Color.maroon);
|
||||
rl.drawText("GAMEPLAY SCREEN", 20, 20, 40, .maroon);
|
||||
rl.drawText(
|
||||
"PRESS ENTER or TAP to JUMP to ENDING SCREEN",
|
||||
130,
|
||||
220,
|
||||
20,
|
||||
rl.Color.maroon,
|
||||
.maroon,
|
||||
);
|
||||
},
|
||||
.ending => {
|
||||
@ -148,21 +148,21 @@ pub fn main() anyerror!void {
|
||||
0,
|
||||
screen_width,
|
||||
screen_height,
|
||||
rl.Color.blue,
|
||||
.blue,
|
||||
);
|
||||
rl.drawText(
|
||||
"ENDING SCREEN",
|
||||
20,
|
||||
20,
|
||||
40,
|
||||
rl.Color.dark_blue,
|
||||
.dark_blue,
|
||||
);
|
||||
rl.drawText(
|
||||
"PRESS ENTER or TAP to RETURN to TITLE SCREEN",
|
||||
120,
|
||||
220,
|
||||
20,
|
||||
rl.Color.dark_blue,
|
||||
.dark_blue,
|
||||
);
|
||||
},
|
||||
}
|
||||
|
||||
@ -26,9 +26,9 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.white);
|
||||
rl.clearBackground(.white);
|
||||
|
||||
rl.drawText("Congrats! You created your first window!", 190, 200, 20, rl.Color.light_gray);
|
||||
rl.drawText("Congrats! You created your first window!", 190, 200, 20, .light_gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
53
examples/core/basic_window_web.zig
Normal file
@ -0,0 +1,53 @@
|
||||
// A raylib-zig port of https://github.com/raysan5/raylib/blob/master/examples/core/core_basic_window_web.c
|
||||
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
const builtin = @import("builtin");
|
||||
|
||||
const emscripten = std.os.emscripten;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Global Variables Definition
|
||||
//----------------------------------------------------------------------------------
|
||||
const screenWidth = 800;
|
||||
const screenHeight = 450;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib-zig [core] example - basic window");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
if (builtin.os.tag == .emscripten) {
|
||||
emscripten.emscripten_set_main_loop(@ptrCast(&updateDrawFrame), 0, 1);
|
||||
} else {
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) { // Detect window close button or ESC key
|
||||
updateDrawFrame();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update and Draw one frame
|
||||
fn updateDrawFrame() void {
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update your variables here
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.white);
|
||||
|
||||
rl.drawText("Congrats! You created your first window!", 190, 200, 20, .light_gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
153
examples/core/core_monitor_change.zig
Normal file
@ -0,0 +1,153 @@
|
||||
// raylib-zig (c) 2025 Maicon Santana (@maiconpintoabreu)
|
||||
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
|
||||
const MAX_MONITORS = 10;
|
||||
|
||||
// Monitor Details
|
||||
const Monitor = struct {
|
||||
position: rl.Vector2,
|
||||
name: [*c]const u8,
|
||||
width: i32,
|
||||
height: i32,
|
||||
physicalWidth: i32,
|
||||
physicalHeight: i32,
|
||||
refreshRate: i32,
|
||||
};
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screenWidth: i32 = 800;
|
||||
const screenHeight: i32 = 450;
|
||||
|
||||
var monitors: [MAX_MONITORS]Monitor = undefined;
|
||||
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib-zig [core] example - monitor change");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
var currentMonitorIndex: i32 = rl.getCurrentMonitor();
|
||||
var monitorCount: usize = 0;
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) { // Detect window close button or ESC key
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Variables to find the max x and Y to calculate the scale
|
||||
var maxWidth: i32 = 1;
|
||||
var maxHeight: i32 = 1;
|
||||
|
||||
// Monitor offset is to fix when monitor position x is negative
|
||||
var monitorOffsetX: f32 = 0;
|
||||
|
||||
// Rebuild monitors array every frame
|
||||
monitorCount = @intCast(rl.getMonitorCount());
|
||||
for (0..monitorCount) |i| {
|
||||
const intI: i32 = @intCast(i);
|
||||
monitors[i] = .{
|
||||
.position = rl.getMonitorPosition(intI),
|
||||
.name = rl.getMonitorName(intI),
|
||||
.width = rl.getMonitorWidth(intI),
|
||||
.height = rl.getMonitorHeight(intI),
|
||||
.physicalWidth = rl.getMonitorPhysicalWidth(intI),
|
||||
.physicalHeight = rl.getMonitorPhysicalHeight(intI),
|
||||
.refreshRate = rl.getMonitorRefreshRate(intI),
|
||||
};
|
||||
if (monitors[i].position.x < monitorOffsetX) {
|
||||
monitorOffsetX = monitors[i].position.x * -1.0;
|
||||
}
|
||||
|
||||
const width: i32 = @as(i32, @intFromFloat(monitors[i].position.x)) + monitors[i].width;
|
||||
const height: i32 = @as(i32, @intFromFloat(monitors[i].position.y)) + monitors[i].height;
|
||||
|
||||
if (maxWidth < width) maxWidth = width;
|
||||
if (maxHeight < height) maxHeight = height;
|
||||
}
|
||||
|
||||
if (rl.isKeyPressed(.enter) and monitorCount > 1) {
|
||||
currentMonitorIndex += 1;
|
||||
|
||||
// Set index to 0 if the last one
|
||||
if (currentMonitorIndex == monitorCount) currentMonitorIndex = 0;
|
||||
|
||||
rl.setWindowMonitor(currentMonitorIndex); // Move window to currentMonitorIndex
|
||||
} else {
|
||||
// Get currentMonitorIndex if manually moved
|
||||
currentMonitorIndex = rl.getCurrentMonitor();
|
||||
}
|
||||
|
||||
var monitorScale: f32 = 0.6;
|
||||
|
||||
const intMonitorOffsetX: i32 = @intFromFloat(monitorOffsetX);
|
||||
|
||||
if (maxHeight > maxWidth + intMonitorOffsetX) {
|
||||
monitorScale *= @as(f32, @floatFromInt(screenHeight)) / @as(f32, @floatFromInt(maxHeight));
|
||||
} else {
|
||||
monitorScale *= @as(f32, @floatFromInt(screenWidth)) / @as(f32, @floatFromInt((maxWidth + intMonitorOffsetX)));
|
||||
}
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawText("Press [Enter] to move window to next monitor available", 20, 20, 20, .dark_gray);
|
||||
|
||||
rl.drawRectangleLines(20, 60, screenWidth - 40, screenHeight - 100, .dark_gray);
|
||||
|
||||
// Draw Monitor Rectangles with information inside
|
||||
for (0..monitorCount) |i| {
|
||||
// Calculate retangle position and size using monitorScale
|
||||
const rec: rl.Rectangle = .{
|
||||
.x = (monitors[i].position.x + monitorOffsetX) * monitorScale + 140,
|
||||
.y = monitors[i].position.y * monitorScale + 80,
|
||||
.width = @as(f32, @floatFromInt(monitors[i].width)) * monitorScale,
|
||||
.height = @as(f32, @floatFromInt(monitors[i].height)) * monitorScale,
|
||||
};
|
||||
|
||||
// Draw monitor name and information inside the rectangle
|
||||
rl.drawText(
|
||||
rl.textFormat("[%i] %s", .{ i, monitors[i].name }),
|
||||
@intFromFloat(rec.x + 10.0),
|
||||
@intFromFloat(rec.y + (100.0 * monitorScale)),
|
||||
@as(i32, @intFromFloat(120.0 * monitorScale)),
|
||||
.blue,
|
||||
);
|
||||
rl.drawText(rl.textFormat("Resolution: [%ipx x %ipx]\nRefreshRate: [%ihz]\nPhysical Size: [%imm x %imm]\nPosition: %3.0f x %3.0f", .{
|
||||
monitors[i].width,
|
||||
monitors[i].height,
|
||||
monitors[i].refreshRate,
|
||||
monitors[i].physicalWidth,
|
||||
monitors[i].physicalHeight,
|
||||
monitors[i].position.x,
|
||||
monitors[i].position.y,
|
||||
}), @intFromFloat(rec.x + 10), @intFromFloat(rec.y + (200 * monitorScale)), @as(i32, @intFromFloat(120.0 * monitorScale)), .dark_gray);
|
||||
|
||||
// Highlight current monitor
|
||||
if (i == currentMonitorIndex) {
|
||||
rl.drawRectangleLinesEx(rec, 5, .red);
|
||||
const windowPosition: rl.Vector2 = .{
|
||||
.x = (rl.getWindowPosition().x + monitorOffsetX) * monitorScale + 140,
|
||||
.y = rl.getWindowPosition().y * monitorScale + 80,
|
||||
};
|
||||
|
||||
// Draw window position based on monitors
|
||||
rl.drawRectangleV(
|
||||
windowPosition,
|
||||
.{ .x = @as(f32, @floatFromInt(screenWidth)) * monitorScale, .y = @as(f32, @floatFromInt(screenHeight)) * monitorScale },
|
||||
rl.fade(.green, 0.5),
|
||||
);
|
||||
} else {
|
||||
rl.drawRectangleLinesEx(rec, 5, .gray);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
102
examples/core/drop_files.zig
Normal file
@ -0,0 +1,102 @@
|
||||
// raylib-zig (c) Leonardo Kreienbuehl 2025
|
||||
|
||||
const rl = @import("raylib");
|
||||
const std = @import("std");
|
||||
|
||||
const MAX_FILEPATH_RECORDED = 4096;
|
||||
const MAX_FILEPATH_SIZE = 2048;
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screenWidth = 800;
|
||||
const screenHeight = 450;
|
||||
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib-zig [core] example - drop files");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
var filePathCounter: usize = 0;
|
||||
var filePaths: [MAX_FILEPATH_RECORDED][MAX_FILEPATH_SIZE]u8 = std.mem.zeroes([MAX_FILEPATH_RECORDED][MAX_FILEPATH_SIZE]u8);
|
||||
|
||||
rl.setTargetFPS(60);
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) {
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (rl.isFileDropped()) {
|
||||
const droppedFiles: rl.FilePathList = rl.loadDroppedFiles();
|
||||
|
||||
for (0..droppedFiles.count) |i| {
|
||||
const offset: usize = @as(usize, @intCast(filePathCounter));
|
||||
const droppedFilePathLength: usize = std.mem.len(droppedFiles.paths[i]);
|
||||
|
||||
if (filePathCounter < (MAX_FILEPATH_RECORDED - 1)) {
|
||||
_ = rl.textCopy(
|
||||
@ptrCast(@constCast(&filePaths[offset])),
|
||||
droppedFiles.paths[i][0..droppedFilePathLength :0],
|
||||
);
|
||||
filePathCounter += 1;
|
||||
}
|
||||
}
|
||||
|
||||
rl.unloadDroppedFiles(droppedFiles);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
|
||||
if (filePathCounter == 0) {
|
||||
rl.drawText(
|
||||
"Drop your files to this window!",
|
||||
100,
|
||||
40,
|
||||
20,
|
||||
rl.Color.dark_gray,
|
||||
);
|
||||
} else {
|
||||
rl.drawText(
|
||||
"Dropped files:",
|
||||
100,
|
||||
40,
|
||||
20,
|
||||
rl.Color.dark_gray,
|
||||
);
|
||||
|
||||
for (0..filePathCounter) |i| {
|
||||
const castedI: i32 = @intCast(i);
|
||||
if (@mod(i, 2) == 0) {
|
||||
rl.drawRectangle(
|
||||
0,
|
||||
85 + 40 * castedI,
|
||||
screenWidth,
|
||||
40,
|
||||
rl.fade(rl.Color.light_gray, 0.5),
|
||||
);
|
||||
} else {
|
||||
rl.drawRectangle(
|
||||
0,
|
||||
85 + 40 * castedI,
|
||||
screenWidth,
|
||||
40,
|
||||
rl.fade(rl.Color.light_gray, 0.3),
|
||||
);
|
||||
}
|
||||
|
||||
rl.drawText(
|
||||
filePaths[i][0 .. MAX_FILEPATH_SIZE - 1 :0],
|
||||
120,
|
||||
100 + 40 * castedI,
|
||||
10,
|
||||
rl.Color.gray,
|
||||
);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
@ -40,11 +40,11 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawText("move the ball with arrow keys", 10, 10, 20, rl.Color.dark_gray);
|
||||
rl.drawText("move the ball with arrow keys", 10, 10, 20, .dark_gray);
|
||||
|
||||
rl.drawCircleV(ballPosition, 50, rl.Color.maroon);
|
||||
rl.drawCircleV(ballPosition, 50, .maroon);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,11 +26,11 @@ pub fn main() anyerror!void {
|
||||
ballPosition.y = @as(f32, @floatFromInt(rl.getMouseY()));
|
||||
|
||||
if (rl.isMouseButtonPressed(.left)) {
|
||||
ballColor = rl.Color.maroon;
|
||||
ballColor = .maroon;
|
||||
} else if (rl.isMouseButtonPressed(.middle)) {
|
||||
ballColor = rl.Color.lime;
|
||||
ballColor = .lime;
|
||||
} else if (rl.isMouseButtonPressed(.right)) {
|
||||
ballColor = rl.Color.dark_blue;
|
||||
ballColor = .dark_blue;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
@ -39,11 +39,11 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawCircleV(ballPosition, 40, ballColor);
|
||||
|
||||
rl.drawText("move ball with mouse and click mouse button to change color", 10, 10, 20, rl.Color.dark_gray);
|
||||
rl.drawText("move ball with mouse and click mouse button to change color", 10, 10, 20, .dark_gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,18 +30,18 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.white);
|
||||
rl.clearBackground(.white);
|
||||
|
||||
rl.drawRectangle(screenWidth / 2 - 40, @as(i32, @intFromFloat(boxPositionY)), 80, 80, rl.Color.maroon);
|
||||
rl.drawRectangle(screenWidth / 2 - 40, @as(i32, @intFromFloat(boxPositionY)), 80, 80, .maroon);
|
||||
|
||||
rl.drawText("Use mouse wheel to move the cube up and down!", 10, 10, 20, rl.Color.gray);
|
||||
rl.drawText("Use mouse wheel to move the cube up and down!", 10, 10, 20, .gray);
|
||||
|
||||
rl.drawText(
|
||||
rl.textFormat("Box position Y: %03i", .{@as(i32, @intFromFloat(boxPositionY))}),
|
||||
10,
|
||||
40,
|
||||
20,
|
||||
rl.Color.light_gray,
|
||||
.light_gray,
|
||||
);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
@ -26,16 +26,16 @@ pub fn main() anyerror!void {
|
||||
//----------------------------------------------------------------------------------
|
||||
ballPosition = rl.getMousePosition();
|
||||
|
||||
ballColor = rl.Color.beige;
|
||||
ballColor = .beige;
|
||||
|
||||
if (rl.isMouseButtonDown(.left)) {
|
||||
ballColor = rl.Color.maroon;
|
||||
ballColor = .maroon;
|
||||
}
|
||||
if (rl.isMouseButtonDown(.middle)) {
|
||||
ballColor = rl.Color.lime;
|
||||
ballColor = .lime;
|
||||
}
|
||||
if (rl.isMouseButtonDown(.right)) {
|
||||
ballColor = rl.Color.dark_blue;
|
||||
ballColor = .dark_blue;
|
||||
}
|
||||
|
||||
if (rl.isMouseButtonPressed(.left)) {
|
||||
@ -58,7 +58,7 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
const nums = [_]i32{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
|
||||
for (nums) |i| {
|
||||
@ -68,13 +68,13 @@ pub fn main() anyerror!void {
|
||||
if ((touchPosition.x >= 0) and (touchPosition.y >= 0)) {
|
||||
|
||||
// Draw circle and touch index number
|
||||
rl.drawCircleV(touchPosition, 34, rl.Color.orange);
|
||||
rl.drawCircleV(touchPosition, 34, .orange);
|
||||
rl.drawText(
|
||||
rl.textFormat("%d", .{i}),
|
||||
@as(i32, @intFromFloat(touchPosition.x)) - 10,
|
||||
@as(i32, @intFromFloat(touchPosition.y)) - 70,
|
||||
40,
|
||||
rl.Color.black,
|
||||
.black,
|
||||
);
|
||||
}
|
||||
}
|
||||
@ -82,8 +82,8 @@ pub fn main() anyerror!void {
|
||||
// Draw the normal mouse location
|
||||
rl.drawCircleV(ballPosition, 30 + (touchCounter * 3), ballColor);
|
||||
|
||||
rl.drawText("move ball with mouse and click mouse button to change color", 10, 10, 20, rl.Color.dark_gray);
|
||||
rl.drawText("touch the screen at multiple locations to get multiple balls", 10, 30, 20, rl.Color.dark_gray);
|
||||
rl.drawText("move ball with mouse and click mouse button to change color", 10, 10, 20, .dark_gray);
|
||||
rl.drawText("touch the screen at multiple locations to get multiple balls", 10, 30, 20, .dark_gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -149,17 +149,17 @@ pub fn main() anyerror!void {
|
||||
defer rl.endDrawing();
|
||||
|
||||
if (rl.isWindowState(rl.ConfigFlags { .window_transparent = true })) {
|
||||
rl.clearBackground(rl.Color.blank);
|
||||
} else rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.blank);
|
||||
} else rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawCircleV(ball_position, ball_radius, rl.Color.maroon);
|
||||
rl.drawCircleV(ball_position, ball_radius, .maroon);
|
||||
rl.drawRectangleLinesEx(
|
||||
rl.Rectangle.init(0, 0, @floatFromInt(rl.getScreenWidth()), @floatFromInt(rl.getScreenHeight())),
|
||||
.init(0, 0, @floatFromInt(rl.getScreenWidth()), @floatFromInt(rl.getScreenHeight())),
|
||||
4,
|
||||
rl.Color.ray_white,
|
||||
.ray_white,
|
||||
);
|
||||
|
||||
rl.drawCircleV(rl.getMousePosition(), 10, rl.Color.dark_blue);
|
||||
rl.drawCircleV(rl.getMousePosition(), 10, .dark_blue);
|
||||
|
||||
rl.drawFPS(10, 10);
|
||||
|
||||
@ -168,7 +168,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
40,
|
||||
10,
|
||||
rl.Color.green,
|
||||
.green,
|
||||
);
|
||||
|
||||
// Draw window state info
|
||||
@ -177,7 +177,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
60,
|
||||
10,
|
||||
rl.Color.gray,
|
||||
.gray,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("[F] flag_fullscreen_mode: %d", .{
|
||||
@ -186,7 +186,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
80,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("[R] flag_window_resizable: %d", .{
|
||||
@ -195,7 +195,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
100,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("[D] flag_window_undecorated: %d", .{
|
||||
@ -204,7 +204,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
120,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("[H] flag_window_hidden: %d", .{
|
||||
@ -213,7 +213,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
140,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("[N] flag_window_minimized: %d", .{
|
||||
@ -222,7 +222,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
160,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("[M] flag_window_maximized: %d", .{
|
||||
@ -231,7 +231,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
180,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("[U] flag_window_unfocused: %d", .{
|
||||
@ -240,7 +240,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
200,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("[T] flag_window_topmost: %d", .{
|
||||
@ -249,7 +249,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
220,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("[A] flag_window_always_run: %d", .{
|
||||
@ -258,7 +258,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
240,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("[V] flag_vsync_hint: %d", .{
|
||||
@ -267,7 +267,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
260,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
|
||||
rl.drawText(
|
||||
@ -275,7 +275,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
300,
|
||||
10,
|
||||
rl.Color.gray,
|
||||
.gray,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("flag_window_highdpi: %d", .{
|
||||
@ -284,7 +284,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
320,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("flag_window_transparent: %d", .{
|
||||
@ -293,7 +293,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
340,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
rl.drawText(
|
||||
rl.textFormat("flag_msaa_4x_hint: %d", .{
|
||||
@ -302,7 +302,7 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
360,
|
||||
10,
|
||||
rl.Color.lime,
|
||||
.lime,
|
||||
);
|
||||
}
|
||||
// ---------------------------------------------------------------------
|
||||
|
||||
60
examples/gui/message_box.zig
Normal file
@ -0,0 +1,60 @@
|
||||
//! # raylib-zig [gui] example - message box
|
||||
//!
|
||||
//! Example originally created with raylib-zig 5.6-dev, last time updated with
|
||||
//! raylib-zig 5.6-dev
|
||||
//!
|
||||
//! 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) Nikolas Wipper 2025
|
||||
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
const rg = @import("raygui");
|
||||
|
||||
/// `rl.getColor` only accepts a `u32`. Performing `@intCast` on the return value
|
||||
/// of `rg.getStyle` invokes checked undefined behavior from Zig when passed to
|
||||
/// `rl.getColor`, hence the custom implementation here...
|
||||
fn getColor(hex: i32) rl.Color {
|
||||
var color: rl.Color = .black;
|
||||
// zig fmt: off
|
||||
color.r = @intCast((hex >> 24) & 0xFF);
|
||||
color.g = @intCast((hex >> 16) & 0xFF);
|
||||
color.b = @intCast((hex >> 8) & 0xFF);
|
||||
color.a = @intCast((hex >> 0) & 0xFF);
|
||||
// zig fmt: on
|
||||
return color;
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
rl.initWindow(400, 200, "raygui - controls test suite");
|
||||
defer rl.closeWindow();
|
||||
|
||||
rl.setTargetFPS(60);
|
||||
|
||||
var show_message_box = false;
|
||||
|
||||
const color_int = rg.getStyle(.default, .{ .default = .background_color });
|
||||
|
||||
while (!rl.windowShouldClose()) {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(getColor(color_int));
|
||||
|
||||
if (rg.button(.init(24, 24, 120, 30), "#191#Show Message"))
|
||||
show_message_box = true;
|
||||
|
||||
if (show_message_box) {
|
||||
const result = rg.messageBox(
|
||||
.init(85, 70, 250, 100),
|
||||
"#191#Message Box",
|
||||
"Hi! This is a message",
|
||||
"Nice;Cool",
|
||||
);
|
||||
|
||||
if (result >= 0) show_message_box = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
148
examples/models/models_bone_socket.zig
Normal file
@ -0,0 +1,148 @@
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
|
||||
const BONE_SOCKETS = 3;
|
||||
const BONE_SOCKET_HAT = 0;
|
||||
const BONE_SOCKET_HAND_R = 1;
|
||||
const BONE_SOCKET_HAND_L = 2;
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
const screenWidth: i32 = 800;
|
||||
const screenHeight: i32 = 450;
|
||||
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib [models] example - bone socket");
|
||||
defer rl.closeWindow();
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
var camera: rl.Camera3D = .{
|
||||
.position = .{ .x = 5.0, .y = 5.0, .z = 5.0 },
|
||||
.target = .{ .x = 0.0, .y = 2.0, .z = 0.0 },
|
||||
.up = .{ .x = 0.0, .y = 1.0, .z = 0.0 },
|
||||
.fovy = 45.0,
|
||||
.projection = .perspective,
|
||||
};
|
||||
|
||||
// Load gltf model
|
||||
var characterModel: rl.Model = try rl.loadModel("examples/models/resources/models/gltf/greenman.glb"); // Load character model
|
||||
defer characterModel.unload();
|
||||
const equipModel: [BONE_SOCKETS]rl.Model = .{
|
||||
try rl.loadModel("examples/models/resources/models/gltf/greenman_hat.glb"), // Index for the hat model is the same as BONE_SOCKET_HAT
|
||||
try rl.loadModel("examples/models/resources/models/gltf/greenman_sword.glb"), // Index for the sword model is the same as BONE_SOCKET_HAND_R
|
||||
try rl.loadModel("examples/models/resources/models/gltf/greenman_shield.glb"), // Index for the shield model is the same as BONE_SOCKET_HAND_L
|
||||
};
|
||||
defer for (equipModel) |model| {
|
||||
model.unload();
|
||||
};
|
||||
|
||||
var showEquip: [3]bool = .{ true, true, true }; // Toggle on/off equip
|
||||
|
||||
// Load gltf model animations
|
||||
var animIndex: usize = 0;
|
||||
var animCurrentFrame: i32 = 0;
|
||||
const modelAnimations = try rl.loadModelAnimations("examples/models/resources/models/gltf/greenman.glb");
|
||||
const animsCount = modelAnimations.len;
|
||||
defer rl.unloadModelAnimations(modelAnimations);
|
||||
|
||||
// indices of bones for sockets
|
||||
var boneSocketIndex: [BONE_SOCKETS]usize = undefined;
|
||||
|
||||
// search bones for sockets
|
||||
for (0..@as(usize, @intCast(characterModel.boneCount))) |i| {
|
||||
const boneName: [:0]const u8 = @ptrCast(&characterModel.bones[i].name);
|
||||
if (rl.textIsEqual(boneName, "socket_hat")) {
|
||||
boneSocketIndex[BONE_SOCKET_HAT] = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rl.textIsEqual(boneName, "socket_hand_R")) {
|
||||
boneSocketIndex[BONE_SOCKET_HAND_R] = i;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (rl.textIsEqual(boneName, "socket_hand_L")) {
|
||||
boneSocketIndex[BONE_SOCKET_HAND_L] = i;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
const position: rl.Vector3 = .zero(); // Set model position
|
||||
var angle: f32 = 0.0; // Set angle for rotate character
|
||||
|
||||
rl.disableCursor(); // Limit cursor to relative movement inside the window
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
|
||||
while (!rl.windowShouldClose()) {
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.updateCamera(&camera, .third_person);
|
||||
|
||||
// Rotate character
|
||||
if (rl.isKeyDown(.f)) {
|
||||
angle += 1.0;
|
||||
angle = @mod(angle, 360.0);
|
||||
} else if (rl.isKeyDown(.h)) {
|
||||
angle -= 1.0;
|
||||
angle = @mod(angle, 360.0);
|
||||
}
|
||||
|
||||
// Select current animation
|
||||
if (rl.isKeyPressed(.t)) animIndex = (animIndex + 1) % animsCount else if (rl.isKeyPressed(.g)) animIndex = (animIndex + animsCount - 1) % animsCount;
|
||||
|
||||
// Toggle shown of equip
|
||||
if (rl.isKeyPressed(.one)) showEquip[BONE_SOCKET_HAT] = !showEquip[BONE_SOCKET_HAT];
|
||||
if (rl.isKeyPressed(.two)) showEquip[BONE_SOCKET_HAND_R] = !showEquip[BONE_SOCKET_HAND_R];
|
||||
if (rl.isKeyPressed(.three)) showEquip[BONE_SOCKET_HAND_L] = !showEquip[BONE_SOCKET_HAND_L];
|
||||
|
||||
// Update model animation
|
||||
const anim = modelAnimations[animIndex];
|
||||
animCurrentFrame = @mod(animCurrentFrame + 1, anim.frameCount);
|
||||
rl.updateModelAnimation(characterModel, anim, animCurrentFrame);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
{
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
{
|
||||
rl.beginMode3D(camera);
|
||||
defer rl.endMode3D();
|
||||
// Draw character
|
||||
const characterRotate: rl.Quaternion = rl.math.quaternionFromAxisAngle(.{ .x = 0.0, .y = 1.0, .z = 0.0 }, angle * std.math.rad_per_deg);
|
||||
characterModel.transform = rl.math.matrixMultiply(rl.math.quaternionToMatrix(characterRotate), rl.math.matrixTranslate(position.x, position.y, position.z));
|
||||
rl.updateModelAnimation(characterModel, anim, animCurrentFrame);
|
||||
rl.drawMesh(characterModel.meshes[0], characterModel.materials[1], characterModel.transform);
|
||||
|
||||
// Draw equipments (hat, sword, shield)
|
||||
for (0..BONE_SOCKETS) |i| {
|
||||
if (!showEquip[i]) continue;
|
||||
|
||||
const transform = &anim.framePoses[@intCast(animCurrentFrame)][boneSocketIndex[i]];
|
||||
const inRotation = characterModel.bindPose[boneSocketIndex[i]].rotation;
|
||||
const outRotation = transform.rotation;
|
||||
|
||||
// Calculate socket rotation (angle between bone in initial pose and same bone in current animation frame)
|
||||
const rotate = rl.math.quaternionMultiply(outRotation, rl.math.quaternionInvert(inRotation));
|
||||
var matrixTransform = rl.math.quaternionToMatrix(rotate);
|
||||
// Translate socket to its position in the current animation
|
||||
matrixTransform = rl.math.matrixMultiply(matrixTransform, rl.math.matrixTranslate(transform.translation.x, transform.translation.y, transform.translation.z));
|
||||
// Transform the socket using the transform of the character (angle and translate)
|
||||
matrixTransform = rl.math.matrixMultiply(matrixTransform, characterModel.transform);
|
||||
|
||||
// Draw mesh at socket position with socket angle rotation
|
||||
rl.drawMesh(equipModel[i].meshes[0], equipModel[i].materials[1], matrixTransform);
|
||||
}
|
||||
|
||||
rl.drawGrid(10, 1.0);
|
||||
}
|
||||
|
||||
rl.drawText("Use the T/G to switch animation", 10, 10, 20, .gray);
|
||||
rl.drawText("Use the F/H to rotate character left/right", 10, 35, 20, .gray);
|
||||
rl.drawText("Use the 1,2,3 to toggle shown of hat, sword and shield", 10, 60, 20, .gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
}
|
||||
119
examples/models/models_box_collisions.zig
Normal file
@ -0,0 +1,119 @@
|
||||
const rl = @import("raylib");
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
const screenWidth: i32 = 800;
|
||||
const screenHeight: i32 = 450;
|
||||
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib [models] example - box collisions");
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
const camera: rl.Camera = .{
|
||||
.position = .{ .x = 0.0, .y = 10.0, .z = 10.0 },
|
||||
.target = .{ .x = 0.0, .y = 0.0, .z = 0.0 },
|
||||
.up = .{ .x = 0.0, .y = 1.0, .z = 0.0 },
|
||||
.fovy = 45.0,
|
||||
.projection = .perspective,
|
||||
};
|
||||
|
||||
var playerPosition: rl.Vector3 = .{ .x = 0.0, .y = 1.0, .z = 2.0 };
|
||||
const playerSize: rl.Vector3 = .{ .x = 1.0, .y = 2.0, .z = 1.0 };
|
||||
var playerColor: rl.Color = .green;
|
||||
|
||||
const enemyBoxPos: rl.Vector3 = .{ .x = -4.0, .y = 1.0, .z = 0.0 };
|
||||
const enemyBoxSize: rl.Vector3 = .{ .x = 2.0, .y = 2.0, .z = 2.0 };
|
||||
|
||||
const enemySpherePos: rl.Vector3 = .{ .x = 4.0, .y = 0.0, .z = 0.0 };
|
||||
const enemySphereSize: f32 = 1.5;
|
||||
|
||||
var collision: bool = false;
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
|
||||
while (!rl.windowShouldClose()) {
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Move player
|
||||
if (rl.isKeyDown(.right)) playerPosition.x += 0.2 else if (rl.isKeyDown(.left)) playerPosition.x -= 0.2 else if (rl.isKeyDown(.down)) playerPosition.z += 0.2 else if (rl.isKeyDown(.up)) playerPosition.z -= 0.2;
|
||||
|
||||
collision = false;
|
||||
|
||||
// Check collisions player vs enemy-box
|
||||
if (rl.checkCollisionBoxes(.{
|
||||
.min = .{
|
||||
.x = playerPosition.x - playerSize.x / 2,
|
||||
.y = playerPosition.y - playerSize.y / 2,
|
||||
.z = playerPosition.z - playerSize.z / 2,
|
||||
},
|
||||
.max = .{
|
||||
.x = playerPosition.x + playerSize.x / 2,
|
||||
.y = playerPosition.y + playerSize.y / 2,
|
||||
.z = playerPosition.z + playerSize.z / 2,
|
||||
},
|
||||
}, .{
|
||||
.min = .{
|
||||
.x = enemyBoxPos.x - enemyBoxSize.x / 2,
|
||||
.y = enemyBoxPos.y - enemyBoxSize.y / 2,
|
||||
.z = enemyBoxPos.z - enemyBoxSize.z / 2,
|
||||
},
|
||||
.max = .{
|
||||
.x = enemyBoxPos.x + enemyBoxSize.x / 2,
|
||||
.y = enemyBoxPos.y + enemyBoxSize.y / 2,
|
||||
.z = enemyBoxPos.z + enemyBoxSize.z / 2,
|
||||
},
|
||||
})) collision = true;
|
||||
|
||||
// Check collisions player vs enemy-sphere
|
||||
if (rl.checkCollisionBoxSphere(.{
|
||||
.min = .{
|
||||
.x = playerPosition.x - playerSize.x / 2,
|
||||
.y = playerPosition.y - playerSize.y / 2,
|
||||
.z = playerPosition.z - playerSize.z / 2,
|
||||
},
|
||||
.max = .{
|
||||
.x = playerPosition.x + playerSize.x / 2,
|
||||
.y = playerPosition.y + playerSize.y / 2,
|
||||
.z = playerPosition.z + playerSize.z / 2,
|
||||
},
|
||||
}, enemySpherePos, enemySphereSize)) collision = true;
|
||||
|
||||
if (collision) playerColor = .red else playerColor = .green;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
{
|
||||
rl.beginMode3D(camera);
|
||||
defer rl.endMode3D();
|
||||
|
||||
// Draw enemy-box
|
||||
rl.drawCube(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, .gray);
|
||||
rl.drawCubeWires(enemyBoxPos, enemyBoxSize.x, enemyBoxSize.y, enemyBoxSize.z, .dark_gray);
|
||||
|
||||
// Draw enemy-sphere
|
||||
rl.drawSphere(enemySpherePos, enemySphereSize, .gray);
|
||||
rl.drawSphereWires(enemySpherePos, enemySphereSize, 16, 16, .dark_gray);
|
||||
|
||||
// Draw player
|
||||
rl.drawCubeV(playerPosition, playerSize, playerColor);
|
||||
|
||||
rl.drawGrid(10, 1.0); // Draw a grid
|
||||
|
||||
}
|
||||
|
||||
rl.drawText("Move player with arrow keys to collide", 220, 40, 20, .gray);
|
||||
|
||||
rl.drawFPS(10, 10);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
@ -28,16 +28,16 @@ pub fn main() anyerror!void {
|
||||
rl.setTargetFPS(60);
|
||||
|
||||
while (!rl.windowShouldClose()) {
|
||||
rl.updateCamera(&camera, rl.CameraMode.orbital);
|
||||
rl.updateCamera(&camera, .orbital);
|
||||
rl.beginDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
rl.beginMode3D(camera);
|
||||
rl.drawModel(model, mapPosition, 1, rl.Color.red);
|
||||
rl.drawModel(model, mapPosition, 1, .red);
|
||||
rl.drawGrid(20, 1.0);
|
||||
rl.endMode3D();
|
||||
rl.drawTexture(texture, screenWidth - texture.width - 20, 20, rl.Color.white);
|
||||
rl.drawRectangleLines(screenWidth - texture.width - 20, 20, texture.width, texture.height, rl.Color.green);
|
||||
rl.drawTexture(texture, screenWidth - texture.width - 20, 20, .white);
|
||||
rl.drawRectangleLines(screenWidth - texture.width - 20, 20, texture.width, texture.height, .green);
|
||||
rl.drawFPS(10, 10);
|
||||
|
||||
rl.endDrawing();
|
||||
|
||||
153
examples/models/models_rlgl_solar_system.zig
Normal file
@ -0,0 +1,153 @@
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
const rlgl = rl.gl;
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
const screenWidth: i32 = 800;
|
||||
const screenHeight: i32 = 450;
|
||||
|
||||
const sunRadius = 4.0;
|
||||
const earthRadius = 0.6;
|
||||
const earthOrbitRadius = 8.0;
|
||||
const moonRadius = 0.16;
|
||||
const moonOrbitRadius = 1.5;
|
||||
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib [models] example - rlgl solar system");
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
var camera: rl.Camera = std.mem.zeroes(rl.Camera);
|
||||
|
||||
camera.position = .{ .x = 16.0, .y = 16.0, .z = 16.0 }; // Camera position
|
||||
camera.target = .{ .x = 0.0, .y = 0.0, .z = 0.0 }; // Camera looking at point
|
||||
camera.up = .{ .x = 0.0, .y = 1.0, .z = 0.0 }; // Camera up vector (rotation towards target)
|
||||
camera.fovy = 45.0; // Camera field-of-view Y
|
||||
camera.projection = .perspective; // Camera projection type
|
||||
|
||||
const rotationSpeed: f32 = 0.2; // General system rotation speed
|
||||
|
||||
var earthRotation: f32 = 0.0; // Rotation of earth around itself (days) in degrees
|
||||
var earthOrbitRotation: f32 = 0.0; // Rotation of earth around the Sun (years) in degrees
|
||||
var moonRotation: f32 = 0.0; // Rotation of moon around itself
|
||||
var moonOrbitRotation: f32 = 0.0; // Rotation of moon around earth in degrees
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
|
||||
while (!rl.windowShouldClose()) {
|
||||
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.updateCamera(&camera, .orbital);
|
||||
|
||||
earthRotation += (5.0 * rotationSpeed);
|
||||
earthOrbitRotation += (365.0 / 360.0 * (5.0 * rotationSpeed) * rotationSpeed);
|
||||
moonRotation += (2.0 * rotationSpeed);
|
||||
moonOrbitRotation += (8.0 * rotationSpeed);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
{
|
||||
rl.beginMode3D(camera);
|
||||
defer rl.endMode3D();
|
||||
|
||||
rlgl.rlPushMatrix();
|
||||
rlgl.rlScalef(sunRadius, sunRadius, sunRadius); // Scale Sun
|
||||
drawSphereBasic(.gold); // Draw the Sun
|
||||
rlgl.rlPopMatrix();
|
||||
|
||||
rlgl.rlPushMatrix();
|
||||
rlgl.rlRotatef(earthOrbitRotation, 0.0, 1.0, 0.0); // Rotation for Earth orbit around Sun
|
||||
rlgl.rlTranslatef(earthOrbitRadius, 0.0, 0.0); // Translation for Earth orbit
|
||||
|
||||
rlgl.rlPushMatrix();
|
||||
rlgl.rlRotatef(earthRotation, 0.25, 1.0, 0.0); // Rotation for Earth itself
|
||||
rlgl.rlScalef(earthRadius, earthRadius, earthRadius); // Scale Earth
|
||||
|
||||
drawSphereBasic(.blue); // Draw the Earth
|
||||
rlgl.rlPopMatrix();
|
||||
|
||||
rlgl.rlRotatef(moonOrbitRotation, 0.0, 1.0, 0.0); // Rotation for Moon orbit around Earth
|
||||
rlgl.rlTranslatef(moonOrbitRadius, 0.0, 0.0); // Translation for Moon orbit
|
||||
rlgl.rlRotatef(moonRotation, 0.0, 1.0, 0.0); // Rotation for Moon itself
|
||||
rlgl.rlScalef(moonRadius, moonRadius, moonRadius); // Scale Moon
|
||||
|
||||
drawSphereBasic(.light_gray); // Draw the Moon
|
||||
rlgl.rlPopMatrix();
|
||||
|
||||
// Some reference elements (not affected by previous matrix transformations)
|
||||
rl.drawCircle3D(.{ .x = 0.0, .y = 0.0, .z = 0.0 }, earthOrbitRadius, .{ .x = 1, .y = 0, .z = 0 }, 90.0, rl.fade(.red, 0.5));
|
||||
rl.drawGrid(20, 1.0);
|
||||
}
|
||||
|
||||
rl.drawText("EARTH ORBITING AROUND THE SUN!", 400, 10, 20, .maroon);
|
||||
rl.drawFPS(10, 10);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// Module Functions Definition
|
||||
//--------------------------------------------------------------------------------------------
|
||||
// Draw sphere without any matrix transformation
|
||||
// NOTE: Sphere is drawn in world position ( 0, 0, 0 ) with radius 1.0f
|
||||
fn drawSphereBasic(color: rl.Color) void {
|
||||
const rings: usize = 16;
|
||||
const slices: usize = 16;
|
||||
const floatRings: f32 = @floatFromInt(rings);
|
||||
const floatSlices: f32 = @floatFromInt(slices);
|
||||
|
||||
// Make sure there is enough space in the internal render batch
|
||||
// buffer to store all required vertex, batch is reseted if required
|
||||
_ = rlgl.rlCheckRenderBatchLimit((rings + 2) * slices * 6);
|
||||
|
||||
rlgl.rlBegin(rlgl.rl_triangles);
|
||||
rlgl.rlColor4ub(color.r, color.g, color.b, color.a);
|
||||
|
||||
for (0..(rings + 2)) |i| {
|
||||
const floatI: f32 = @floatFromInt(i);
|
||||
for (0..slices) |j| {
|
||||
const floatJ: f32 = @floatFromInt(j);
|
||||
rlgl.rlVertex3f(
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * floatI)) * std.math.sin(std.math.rad_per_deg * (floatJ * 360 / floatSlices)),
|
||||
std.math.sin(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * floatI)),
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * floatI)) * std.math.cos(std.math.rad_per_deg * (floatJ * 360 / floatSlices)),
|
||||
);
|
||||
rlgl.rlVertex3f(
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI + 1.0))) * std.math.sin(std.math.rad_per_deg * ((floatJ + 1.0) * 360 / floatSlices)),
|
||||
std.math.sin(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI + 1.0))),
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI + 1.0))) * std.math.cos(std.math.rad_per_deg * ((floatJ + 1.0) * 360 / floatSlices)),
|
||||
);
|
||||
rlgl.rlVertex3f(
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI + 1.0))) * std.math.sin(std.math.rad_per_deg * (floatJ * 360 / floatSlices)),
|
||||
std.math.sin(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI + 1.0))),
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI + 1.0))) * std.math.cos(std.math.rad_per_deg * (floatJ * 360 / floatSlices)),
|
||||
);
|
||||
|
||||
rlgl.rlVertex3f(
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * floatI)) * std.math.sin(std.math.rad_per_deg * (floatJ * 360 / floatSlices)),
|
||||
std.math.sin(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * floatI)),
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * floatI)) * std.math.cos(std.math.rad_per_deg * (floatJ * 360 / floatSlices)),
|
||||
);
|
||||
rlgl.rlVertex3f(
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI))) * std.math.sin(std.math.rad_per_deg * ((floatJ + 1.0) * 360 / floatSlices)),
|
||||
std.math.sin(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI))),
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI))) * std.math.cos(std.math.rad_per_deg * ((floatJ + 1.0) * 360 / floatSlices)),
|
||||
);
|
||||
rlgl.rlVertex3f(
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI + 1.0))) * std.math.sin(std.math.rad_per_deg * ((floatJ + 1.0) * 360 / floatSlices)),
|
||||
std.math.sin(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI + 1.0))),
|
||||
std.math.cos(std.math.rad_per_deg * (270.0 + (180.0 / (floatRings + 1.0)) * (floatI + 1.0))) * std.math.cos(std.math.rad_per_deg * ((floatJ + 1.0) * 360 / floatSlices)),
|
||||
);
|
||||
}
|
||||
}
|
||||
rlgl.rlEnd();
|
||||
}
|
||||
5
examples/models/resources/models/gltf/LICENSE
Normal file
@ -0,0 +1,5 @@
|
||||
robot.glb model by @Quaternius (https://www.patreon.com/quaternius)
|
||||
Licensed under CC0 1.0 Universal (CC0 1.0) - Public Domain Dedication (https://creativecommons.org/publicdomain/zero/1.0/)
|
||||
|
||||
greenman.glb, greenman_hat.glb, greenman_sword.glb, greenman_shield.glb models by @iP (https://github.com/ipzaur)
|
||||
Licensed under CC0 1.0 Universal (CC0 1.0) - Public Domain Dedication (https://creativecommons.org/publicdomain/zero/1.0/)
|
||||
BIN
examples/models/resources/models/gltf/greenman.glb
Normal file
BIN
examples/models/resources/models/gltf/greenman_hat.glb
Normal file
BIN
examples/models/resources/models/gltf/greenman_shield.glb
Normal file
BIN
examples/models/resources/models/gltf/greenman_sword.glb
Normal file
@ -87,7 +87,7 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
// We only draw a white full-screen rectangle,
|
||||
// frame is generated in shader using raymarching
|
||||
@ -100,7 +100,7 @@ pub fn main() anyerror!void {
|
||||
0,
|
||||
rl.getScreenWidth(),
|
||||
rl.getScreenHeight(),
|
||||
rl.Color.white,
|
||||
.white,
|
||||
);
|
||||
}
|
||||
|
||||
@ -109,7 +109,7 @@ pub fn main() anyerror!void {
|
||||
rl.getScreenWidth() - 280,
|
||||
rl.getScreenHeight() - 20,
|
||||
10,
|
||||
rl.Color.black,
|
||||
.black,
|
||||
);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
4
examples/shaders/resources/LICENSE.md
Normal file
@ -0,0 +1,4 @@
|
||||
| resource | author | licence | notes |
|
||||
| :----------------- | :-----------: | :------ | :---- |
|
||||
| fudesumi.png | [Eiden Marsal](https://www.artstation.com/marshall_z) | [CC-BY-NC](https://creativecommons.org/licenses/by-nc/4.0/) | - |
|
||||
| raysan.png | [@raysan5](https://github.com/raysan5) | [CC0](https://creativecommons.org/publicdomain/zero/1.0/) | - |
|
||||
BIN
examples/shaders/resources/fudesumi.png
Normal file
|
After Width: | Height: | Size: 218 KiB |
BIN
examples/shaders/resources/raysan.png
Normal file
|
After Width: | Height: | Size: 5.6 KiB |
80
examples/shaders/resources/shaders/glsl100/ascii.fs
Normal file
@ -0,0 +1,80 @@
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input from the vertex shader
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
// Output color for the screen
|
||||
varying vec4 finalColor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec2 resolution;
|
||||
|
||||
// Fontsize less then 9 may be not complete
|
||||
uniform float fontSize;
|
||||
|
||||
float GreyScale(in vec3 col)
|
||||
{
|
||||
return dot(col, vec3(0.2126, 0.7152, 0.0722));
|
||||
}
|
||||
|
||||
float GetCharacter(float n, vec2 p)
|
||||
{
|
||||
p = floor(p*vec2(-4.0, 4.0) + 2.5);
|
||||
|
||||
// Check if the calculated coordinate is inside the 5x5 grid (from 0.0 to 4.0)
|
||||
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
|
||||
{
|
||||
float a = floor(p.x + 0.5) + 5.0*floor(p.y + 0.5);
|
||||
|
||||
// This checked if the 'a'-th bit of 'n' was set
|
||||
float shiftedN = floor(n/pow(2.0, a));
|
||||
|
||||
if (mod(shiftedN, 2.0) == 1.0)
|
||||
{
|
||||
return 1.0; // The bit is on
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0; // The bit is off, or we are outside the grid
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Main shader logic
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 charPixelSize = vec2(fontSize, fontSize);
|
||||
vec2 uvCellSize = charPixelSize/resolution;
|
||||
|
||||
// The cell size is based on the fontSize set by application
|
||||
vec2 cellUV = floor(fragTexCoord/uvCellSize)*uvCellSize;
|
||||
|
||||
vec3 cellColor = texture2D(texture0, cellUV).rgb;
|
||||
|
||||
// Gray is used to define what character will be selected to draw
|
||||
float gray = GreyScale(cellColor);
|
||||
|
||||
float n = 4096.0;
|
||||
|
||||
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||
if (gray > 0.2) n = 65600.0; // :
|
||||
if (gray > 0.3) n = 18725316.0; // v
|
||||
if (gray > 0.4) n = 15255086.0; // o
|
||||
if (gray > 0.5) n = 13121101.0; // &
|
||||
if (gray > 0.6) n = 15252014.0; // 8
|
||||
if (gray > 0.7) n = 13195790.0; // @
|
||||
if (gray > 0.8) n = 11512810.0; // #
|
||||
|
||||
vec2 localUV = (fragTexCoord - cellUV)/uvCellSize; // Range [0.0, 1.0]
|
||||
|
||||
vec2 p = localUV*2.0 - 1.0; // Range [-1.0, 1.0]
|
||||
|
||||
// cellColor and charShape will define the color of the char
|
||||
vec3 color = cellColor*GetCharacter(n, p);
|
||||
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
}
|
||||
78
examples/shaders/resources/shaders/glsl120/ascii.fs
Normal file
@ -0,0 +1,78 @@
|
||||
#version 120
|
||||
|
||||
// Input from the vertex shader
|
||||
varying vec2 fragTexCoord;
|
||||
|
||||
// Output color for the screen
|
||||
varying vec4 finalColor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec2 resolution;
|
||||
|
||||
// Fontsize less then 9 may be not complete
|
||||
uniform float fontSize;
|
||||
|
||||
float GreyScale(in vec3 col)
|
||||
{
|
||||
return dot(col, vec3(0.2126, 0.7152, 0.0722));
|
||||
}
|
||||
|
||||
float GetCharacter(float n, vec2 p)
|
||||
{
|
||||
p = floor(p*vec2(-4.0, 4.0) + 2.5);
|
||||
|
||||
// Check if the calculated coordinate is inside the 5x5 grid (from 0.0 to 4.0)
|
||||
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
|
||||
{
|
||||
float a = floor(p.x + 0.5) + 5.0*floor(p.y + 0.5);
|
||||
|
||||
// This checked if the 'a'-th bit of 'n' was set
|
||||
float shiftedN = floor(n/pow(2.0, a));
|
||||
|
||||
if (mod(shiftedN, 2.0) == 1.0)
|
||||
{
|
||||
return 1.0; // The bit is on
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0; // The bit is off, or we are outside the grid
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Main shader logic
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 charPixelSize = vec2(fontSize, fontSize);
|
||||
vec2 uvCellSize = charPixelSize / resolution;
|
||||
|
||||
// The cell size is based on the fontSize set by application
|
||||
vec2 cellUV = floor(fragTexCoord / uvCellSize)*uvCellSize;
|
||||
|
||||
vec3 cellColor = texture2D(texture0, cellUV).rgb;
|
||||
|
||||
// Gray is used to define what character will be selected to draw
|
||||
float gray = GreyScale(cellColor);
|
||||
|
||||
float n = 4096.0;
|
||||
|
||||
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||
if (gray > 0.2) n = 65600.0; // :
|
||||
if (gray > 0.3) n = 18725316.0; // v
|
||||
if (gray > 0.4) n = 15255086.0; // o
|
||||
if (gray > 0.5) n = 13121101.0; // &
|
||||
if (gray > 0.6) n = 15252014.0; // 8
|
||||
if (gray > 0.7) n = 13195790.0; // @
|
||||
if (gray > 0.8) n = 11512810.0; // #
|
||||
|
||||
vec2 localUV = (fragTexCoord - cellUV)/uvCellSize; // Range [0.0, 1.0]
|
||||
|
||||
vec2 p = localUV*2.0 - 1.0; // Range [-1.0, 1.0]
|
||||
|
||||
// cellColor and charShape will define the color of the char
|
||||
vec3 color = cellColor*GetCharacter(n, p);
|
||||
|
||||
gl_FragColor = vec4(color, 1.0);
|
||||
}
|
||||
73
examples/shaders/resources/shaders/glsl330/ascii.fs
Normal file
@ -0,0 +1,73 @@
|
||||
#version 330
|
||||
|
||||
// Input from the vertex shader
|
||||
in vec2 fragTexCoord;
|
||||
|
||||
// Output color for the screen
|
||||
out vec4 finalColor;
|
||||
|
||||
uniform sampler2D texture0;
|
||||
uniform vec2 resolution;
|
||||
|
||||
// Fontsize less then 9 may be not complete
|
||||
uniform float fontSize;
|
||||
|
||||
float GreyScale(in vec3 col)
|
||||
{
|
||||
return dot(col, vec3(0.2126, 0.7152, 0.0722));
|
||||
}
|
||||
|
||||
float GetCharacter(int n, vec2 p)
|
||||
{
|
||||
p = floor(p*vec2(-4.0, 4.0) + 2.5);
|
||||
|
||||
// Check if the coordinate is inside the 5x5 grid (0 to 4)
|
||||
if (clamp(p.x, 0.0, 4.0) == p.x && clamp(p.y, 0.0, 4.0) == p.y)
|
||||
{
|
||||
int a = int(round(p.x) + 5.0*round(p.y));
|
||||
if (((n >> a) & 1) == 1)
|
||||
{
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
return 0.0; // The bit is off, or we are outside the grid
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Main shader logic
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 charPixelSize = vec2(fontSize, fontSize);
|
||||
vec2 uvCellSize = charPixelSize/resolution;
|
||||
|
||||
// The cell size is based on the fontSize set by application
|
||||
vec2 cellUV = floor(fragTexCoord/uvCellSize)*uvCellSize;
|
||||
|
||||
vec3 cellColor = texture(texture0, cellUV).rgb;
|
||||
|
||||
// Gray is used to define what character will be selected to draw
|
||||
float gray = GreyScale(cellColor);
|
||||
|
||||
int n = 4096;
|
||||
|
||||
// Character set from https://www.shadertoy.com/view/lssGDj
|
||||
// Create new bitmaps https://thrill-project.com/archiv/coding/bitmap/
|
||||
if (gray > 0.2) n = 65600; // :
|
||||
if (gray > 0.3) n = 18725316; // v
|
||||
if (gray > 0.4) n = 15255086; // o
|
||||
if (gray > 0.5) n = 13121101; // &
|
||||
if (gray > 0.6) n = 15252014; // 8
|
||||
if (gray > 0.7) n = 13195790; // @
|
||||
if (gray > 0.8) n = 11512810; // #
|
||||
|
||||
vec2 localUV = (fragTexCoord - cellUV)/uvCellSize; // Range [0.0, 1.0]
|
||||
|
||||
vec2 p = localUV*2.0 - 1.0; // Range [-1.0, 1.0]
|
||||
|
||||
vec3 color = cellColor*GetCharacter(n, p);
|
||||
|
||||
finalColor = vec4(color, 1.0);
|
||||
}
|
||||
100
examples/shaders/shaders_ascii_rendering.zig
Normal file
@ -0,0 +1,100 @@
|
||||
// raylib-zig (c) 2025 Maicon Santana (@maiconpintoabreu)
|
||||
|
||||
const builtin = @import("builtin");
|
||||
const rl = @import("raylib");
|
||||
|
||||
const GLSL_VERSION: i16 = if (builtin.cpu.arch.isWasm()) 100 else 330;
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screenWidth = 800;
|
||||
const screenHeight = 450;
|
||||
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib-zig [core] example - monitor change");
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
// Texture to test static drawing
|
||||
const fudesumi: rl.Texture2D = try rl.loadTexture("examples/shaders/resources/fudesumi.png");
|
||||
defer fudesumi.unload();
|
||||
// Texture to test moving drawing
|
||||
const raysan: rl.Texture2D = try rl.loadTexture("examples/shaders/resources/raysan.png");
|
||||
defer raysan.unload();
|
||||
|
||||
// Load shader to be used on postprocessing
|
||||
const shader: rl.Shader = try rl.loadShader(
|
||||
null,
|
||||
rl.textFormat("examples/shaders/resources/shaders/glsl%i/ascii.fs", .{GLSL_VERSION}),
|
||||
);
|
||||
|
||||
// These locations are used to send data to the GPU
|
||||
const resolutionLoc: i32 = rl.getShaderLocation(shader, "resolution");
|
||||
const fontSizeLoc: i32 = rl.getShaderLocation(shader, "fontSize");
|
||||
|
||||
// Set the character size for the ASCII effect
|
||||
// Fontsize should be 9 or more
|
||||
var fontSize: f32 = 9.0;
|
||||
|
||||
// Send the updated values to the shader
|
||||
const resolution: rl.Vector2 = .{ .x = @floatFromInt(screenWidth), .y = @floatFromInt(screenHeight) };
|
||||
rl.setShaderValue(shader, resolutionLoc, &resolution, .vec2);
|
||||
|
||||
var circlePos: rl.Vector2 = .{ .x = 40.0, .y = @as(f32, @floatFromInt(screenHeight)) * 0.5 };
|
||||
var circleSpeed: f32 = 1.0;
|
||||
|
||||
// RenderTexture to apply the postprocessing later
|
||||
const target: rl.RenderTexture2D = try rl.loadRenderTexture(screenWidth, screenHeight);
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) { // Detect window close button or ESC key
|
||||
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
circlePos.x += circleSpeed;
|
||||
if ((circlePos.x > 200.0) or (circlePos.x < 40.0)) circleSpeed *= -1; // Revert speed
|
||||
|
||||
if (rl.isKeyPressed(.left) and (fontSize > 9.0)) fontSize -= 1.0; // Reduce fontSize
|
||||
if (rl.isKeyPressed(.right) and (fontSize < 15.0)) fontSize += 1.0; // Increase fontSize
|
||||
|
||||
// Set fontsize for the shader
|
||||
rl.setShaderValue(shader, fontSizeLoc, &fontSize, .float);
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
{
|
||||
rl.beginTextureMode(target);
|
||||
defer rl.endTextureMode();
|
||||
|
||||
rl.clearBackground(.white);
|
||||
|
||||
// Draw scene in our render texture
|
||||
rl.drawTexture(fudesumi, 500, -30, .white);
|
||||
rl.drawTextureV(raysan, circlePos, .white);
|
||||
}
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
rl.clearBackground(.ray_white);
|
||||
{
|
||||
rl.beginShaderMode(shader);
|
||||
defer rl.endShaderMode();
|
||||
// Draw the scene texture (that we rendered earlier) to the screen
|
||||
// The shader will process every pixel of this texture
|
||||
rl.drawTextureRec(target.texture, .{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = @floatFromInt(target.texture.width),
|
||||
.height = -@as(f32, @floatFromInt(target.texture.height)),
|
||||
}, .zero(), .white);
|
||||
}
|
||||
|
||||
rl.drawRectangle(0, 0, screenWidth, 40, .black);
|
||||
rl.drawText(rl.textFormat("Ascii effect - FontSize:%2.0f - [Left] -1 [Right] +1 ", .{fontSize}), 120, 10, 20, .light_gray);
|
||||
rl.drawFPS(10, 10);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
366
examples/shaders/shaders_basic_pbr.zig
Normal file
@ -0,0 +1,366 @@
|
||||
// raylib [shaders] example - Basic PBR
|
||||
//
|
||||
// Example complexity rating: [★★★★] 4/4
|
||||
//
|
||||
// Example originally created with raylib 5.0, last time updated with raylib 5.1-dev
|
||||
//
|
||||
// Example contributed by Afan OLOVCIC (@_DevDad) and reviewed by Ramon Santamaria (@raysan5)
|
||||
//
|
||||
// Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
// BSD-like license that allows static linking with closed source software
|
||||
//
|
||||
// Copyright (c) 2023-2025 Afan OLOVCIC (@_DevDad)
|
||||
//
|
||||
// Model: "Old Rusty Car" (https://skfb.ly/LxRy) by Renafox,
|
||||
// licensed under Creative Commons Attribution-NonCommercial
|
||||
// (http://creativecommons.org/licenses/by-nc/4.0/)
|
||||
|
||||
const rl = @import("raylib");
|
||||
|
||||
/// Casts ShaderLocationIndex to a u32
|
||||
fn uSli(sli: rl.ShaderLocationIndex) u32 {
|
||||
return @intCast(@intFromEnum(sli));
|
||||
}
|
||||
|
||||
/// Casts MaterialMapIndex to a u32
|
||||
fn uMmi(mmi: rl.MaterialMapIndex) u32 {
|
||||
return @intCast(@intFromEnum(mmi));
|
||||
}
|
||||
|
||||
/// Max dynamic lights supported by shader
|
||||
const max_lights = 4;
|
||||
/// Current number of dynamic lights that have been created
|
||||
var light_count: u32 = 0;
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Types and Structures Definition
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/// Light data
|
||||
const Light = extern struct {
|
||||
type: Type = .directional,
|
||||
enabled: bool = false,
|
||||
_enabled_pad1: u8 = 0,
|
||||
_enabled_pad2: @Type(.{.int = .{
|
||||
.signedness = .unsigned,
|
||||
.bits = @bitSizeOf(c_uint) - 16,
|
||||
}}) = 0,
|
||||
position: rl.Vector3 = .init(0, 0, 0),
|
||||
target: rl.Vector3 = .init(0, 0, 0),
|
||||
color: [4]f32 = .{ 0, 0, 0, 0 },
|
||||
intensity: f32 = 0,
|
||||
|
||||
// Shader light parameters locations
|
||||
loc: extern struct {
|
||||
type: i32 = 0,
|
||||
enabled: i32 = 0,
|
||||
position: i32 = 0,
|
||||
target: i32 = 0,
|
||||
color: i32 = 0,
|
||||
intensity: i32 = 0,
|
||||
} = .{},
|
||||
|
||||
/// Light type
|
||||
const Type = enum(c_uint) {
|
||||
directional = 0,
|
||||
point,
|
||||
spot,
|
||||
};
|
||||
|
||||
/// Create light with provided data
|
||||
///
|
||||
/// NOTE: It updates `light_count` and is limited to `max_lights`
|
||||
fn init(
|
||||
t: Type,
|
||||
position: rl.Vector3,
|
||||
target: rl.Vector3,
|
||||
color: rl.Color,
|
||||
intensity: f32,
|
||||
shader: rl.Shader,
|
||||
) Light {
|
||||
if (light_count >= max_lights) {
|
||||
return .{};
|
||||
}
|
||||
const light: Light = .{
|
||||
.type = t,
|
||||
.enabled = true,
|
||||
.position = position,
|
||||
.target = target,
|
||||
.color = .{
|
||||
@as(f32, @floatFromInt(color.r)) / 255.0,
|
||||
@as(f32, @floatFromInt(color.g)) / 255.0,
|
||||
@as(f32, @floatFromInt(color.b)) / 255.0,
|
||||
@as(f32, @floatFromInt(color.a)) / 255.0,
|
||||
},
|
||||
.intensity = intensity,
|
||||
|
||||
// NOTE: Shader parameters names for lights must match the requested ones
|
||||
.loc = .{
|
||||
.type = rl.getShaderLocation(shader, rl.textFormat("lights[%i].type", .{ light_count })),
|
||||
.enabled = rl.getShaderLocation(shader, rl.textFormat("lights[%i].enabled", .{ light_count })),
|
||||
.position = rl.getShaderLocation(shader, rl.textFormat("lights[%i].position", .{ light_count })),
|
||||
.target = rl.getShaderLocation(shader, rl.textFormat("lights[%i].target", .{ light_count })),
|
||||
.color = rl.getShaderLocation(shader, rl.textFormat("lights[%i].color", .{ light_count })),
|
||||
.intensity = rl.getShaderLocation(shader, rl.textFormat("lights[%i].intensity", .{ light_count })),
|
||||
},
|
||||
};
|
||||
light.update(shader);
|
||||
light_count += 1;
|
||||
|
||||
return light;
|
||||
}
|
||||
|
||||
/// Send light properties to shader
|
||||
///
|
||||
/// NOTE: Light shader locations should be available
|
||||
fn update(self: Light, shader: rl.Shader) void {
|
||||
rl.setShaderValue(shader, self.loc.type, &self.type, .int);
|
||||
rl.setShaderValue(shader, self.loc.enabled, &self.enabled, .int);
|
||||
|
||||
// Send to shader light position values
|
||||
const position: [3]f32 = .{ self.position.x, self.position.y, self.position.z };
|
||||
rl.setShaderValue(shader, self.loc.position, &position, .vec3);
|
||||
|
||||
// Send to shader light target position values
|
||||
const target: [3]f32 = .{ self.target.x, self.target.y, self.target.z };
|
||||
rl.setShaderValue(shader, self.loc.target, &target, .vec3);
|
||||
rl.setShaderValue(shader, self.loc.color, &self.color, .vec4);
|
||||
rl.setShaderValue(shader, self.loc.intensity, &self.intensity, .float);
|
||||
}
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
// Main Entry Point
|
||||
//----------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.setConfigFlags(.{ .msaa_4x_hint = true });
|
||||
rl.initWindow(screen_width, screen_height, "raylib [shaders] example - basic pbr");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
var camera: rl.Camera = .{
|
||||
.position = .init(2, 2, 6), // Camera position
|
||||
.target = .init(0, 0.5, 0), // Camera looking at point
|
||||
.up = .init(0, 1, 0), // Camera up vector (rotation towards target)
|
||||
.fovy = 45, // Camera field-of-view Y
|
||||
.projection = .perspective, // Camera projection type
|
||||
};
|
||||
|
||||
// Load PBR shader and setup all required locations
|
||||
const shader: rl.Shader = try rl.loadShader(
|
||||
"resources/shaders/glsl330/pbr.vs",
|
||||
"resources/shaders/glsl330/pbr.fs",
|
||||
);
|
||||
defer rl.unloadShader(shader);
|
||||
|
||||
shader.locs[uSli(.map_albedo)] = rl.getShaderLocation(shader, "albedoMap");
|
||||
// WARNING: Metalness, roughness, and ambient occlusion are all packed into a MRA texture
|
||||
// They are passed as to the SHADER_LOC_MAP_METALNESS location for convenience,
|
||||
// shader already takes care of it accordingly
|
||||
shader.locs[uSli(.map_metalness)] = rl.getShaderLocation(shader, "mraMap");
|
||||
shader.locs[uSli(.map_normal)] = rl.getShaderLocation(shader, "normalMap");
|
||||
// WARNING: Similar to the MRA map, the emissive map packs different information
|
||||
// into a single texture: it stores height and emission data
|
||||
// It is binded to SHADER_LOC_MAP_EMISSION location an properly processed on shader
|
||||
shader.locs[uSli(.map_emission)] = rl.getShaderLocation(shader, "emissiveMap");
|
||||
shader.locs[uSli(.color_diffuse)] = rl.getShaderLocation(shader, "albedoColor");
|
||||
|
||||
// Setup additional required shader locations, including lights data
|
||||
shader.locs[uSli(.vector_view)] = rl.getShaderLocation(shader, "viewPos");
|
||||
const loc_light_count: i32 = rl.getShaderLocation(shader, "numOfLights");
|
||||
const max_light_count: i32 = max_lights;
|
||||
rl.setShaderValue(shader, loc_light_count, &max_light_count, .int);
|
||||
|
||||
// Setup ambient color and intensity parameters
|
||||
const ambient_intensity: f32 = 0.02;
|
||||
const ambient_color: rl.Vector3 = blk: {
|
||||
const c: rl.Color = .init(26, 32, 135, 255);
|
||||
break :blk .init(
|
||||
@as(f32, @floatFromInt(c.r)) / 255.0,
|
||||
@as(f32, @floatFromInt(c.g)) / 255.0,
|
||||
@as(f32, @floatFromInt(c.b)) / 255.0,
|
||||
);
|
||||
};
|
||||
rl.setShaderValue(shader, rl.getShaderLocation(shader, "ambientColor"), &ambient_color, .vec3);
|
||||
rl.setShaderValue(shader, rl.getShaderLocation(shader, "ambient"), &ambient_intensity, .float);
|
||||
|
||||
// Get location for shader parameters that can be modified in real time
|
||||
const loc_metallic_value = rl.getShaderLocation(shader, "metallicValue");
|
||||
const loc_roughness_value = rl.getShaderLocation(shader, "roughnessValue");
|
||||
const loc_emissive_intensity = rl.getShaderLocation(shader, "emissivePower");
|
||||
const loc_emissive_color = rl.getShaderLocation(shader, "emissiveColor");
|
||||
const loc_texture_tiling = rl.getShaderLocation(shader, "tiling");
|
||||
|
||||
// Load old car model using PBR maps and shader
|
||||
// WARNING: We know this model consists of a single model.meshes[0] and
|
||||
// that model.materials[0] is by default assigned to that mesh
|
||||
// There could be more complex models consisting of multiple meshes and
|
||||
// multiple materials defined for those meshes... but always 1 mesh = 1 material
|
||||
const car: rl.Model = try .init("resources/models/old_car_new.glb");
|
||||
defer {
|
||||
car.materials[0].shader = .{ .id = 0, .locs = null };
|
||||
rl.unloadMaterial(car.materials[0]);
|
||||
car.materials[0].maps = null;
|
||||
car.unload();
|
||||
}
|
||||
|
||||
// Assign already setup PBR shader to model.materials[0], used by models.meshes[0]
|
||||
car.materials[0].shader = shader;
|
||||
|
||||
// Setup materials[0].maps default parameters
|
||||
car.materials[0].maps[uMmi(.albedo)].color = .white;
|
||||
car.materials[0].maps[uMmi(.metalness)].value = 1.0;
|
||||
car.materials[0].maps[uMmi(.roughness)].value = 0.0;
|
||||
car.materials[0].maps[uMmi(.occlusion)].value = 1.0;
|
||||
car.materials[0].maps[uMmi(.emission)].color = .init(255, 162, 0, 255);
|
||||
|
||||
// Setup materials[0].maps default textures
|
||||
car.materials[0].maps[uMmi(.albedo)].texture = try .init("resources/textures/old_car_d.png");
|
||||
car.materials[0].maps[uMmi(.metalness)].texture = try .init("resources/textures/old_car_mra.png");
|
||||
car.materials[0].maps[uMmi(.normal)].texture = try .init("resources/textures/old_car_n.png");
|
||||
car.materials[0].maps[uMmi(.emission)].texture = try .init("resources/textures/old_car_e.png");
|
||||
|
||||
// Load floor model mesh and assign material parameters
|
||||
// NOTE: A basic plane shape can be generated instead of being loaded from a model file
|
||||
const floor: rl.Model = try .init("resources/models/plane.glb");
|
||||
defer {
|
||||
floor.materials[0].shader = .{ .id = 0, .locs = null };
|
||||
rl.unloadMaterial(floor.materials[0]);
|
||||
floor.materials[0].maps = null;
|
||||
floor.unload();
|
||||
}
|
||||
//Mesh floorMesh = GenMeshPlane(10, 10, 10, 10);
|
||||
//GenMeshTangents(&floorMesh); // TODO: Review tangents generation
|
||||
//Model floor = LoadModelFromMesh(floorMesh);
|
||||
|
||||
// Assign material shader for our floor model, same PBR shader
|
||||
floor.materials[0].shader = shader;
|
||||
|
||||
floor.materials[0].maps[uMmi(.albedo)].color = .white;
|
||||
floor.materials[0].maps[uMmi(.metalness)].value = 0.8;
|
||||
floor.materials[0].maps[uMmi(.roughness)].value = 0.1;
|
||||
floor.materials[0].maps[uMmi(.occlusion)].value = 1.0;
|
||||
floor.materials[0].maps[uMmi(.emission)].color = .black;
|
||||
|
||||
floor.materials[0].maps[uMmi(.albedo)].texture = try .init("resources/textures/road_a.png");
|
||||
floor.materials[0].maps[uMmi(.metalness)].texture = try .init("resources/textures/road_mra.png");
|
||||
floor.materials[0].maps[uMmi(.normal)].texture = try .init("resources/textures/road_n.png");
|
||||
|
||||
// Models texture tiling parameter can be stored in the Material struct if required (CURRENTLY NOT USED)
|
||||
// NOTE: Material.params[4] are available for generic parameters storage (float)
|
||||
const car_texture_tiling: rl.Vector2 = .init(0.5, 0.5);
|
||||
const floor_texture_tiling: rl.Vector2 = .init(0.5, 0.5);
|
||||
|
||||
// Create some lights
|
||||
var lights: [max_lights]Light = .{
|
||||
.init(.point, .init(-1, 1, -2), .init(0, 0, 0), .yellow, 4, shader),
|
||||
.init(.point, .init(2, 1, 1), .init(0, 0, 0), .green, 3.3, shader),
|
||||
.init(.point, .init(-2, 1, 1), .init(0, 0, 0), .red, 8.3, shader),
|
||||
.init(.point, .init(1, 1, -2), .init(0, 0, 0), .blue, 2, shader),
|
||||
};
|
||||
|
||||
// Setup material texture maps usage in shader
|
||||
// NOTE: By default, the texture maps are always used
|
||||
const usage: i32 = 1;
|
||||
rl.setShaderValue(shader, rl.getShaderLocation(shader, "useTexAlbedo"), &usage, .int);
|
||||
rl.setShaderValue(shader, rl.getShaderLocation(shader, "useTexNormal"), &usage, .int);
|
||||
rl.setShaderValue(shader, rl.getShaderLocation(shader, "useTexMRA"), &usage, .int);
|
||||
rl.setShaderValue(shader, rl.getShaderLocation(shader, "useTexEmissive"), &usage, .int);
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//---------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
camera.update(.orbital);
|
||||
|
||||
// Update the shader with the camera view vector (points towards { 0.0f, 0.0f, 0.0f })
|
||||
const camera_pos: [3]f32 = .{ camera.position.x, camera.position.y, camera.position.z };
|
||||
rl.setShaderValue(shader, shader.locs[uSli(.vector_view)], &camera_pos, .vec3);
|
||||
|
||||
// Check key inputs to enable/disable lights
|
||||
if (rl.isKeyPressed(.one)) {
|
||||
lights[2].enabled = !lights[2].enabled;
|
||||
}
|
||||
if (rl.isKeyPressed(.two)) {
|
||||
lights[1].enabled = !lights[1].enabled;
|
||||
}
|
||||
if (rl.isKeyPressed(.three)) {
|
||||
lights[3].enabled = !lights[3].enabled;
|
||||
}
|
||||
if (rl.isKeyPressed(.four)) {
|
||||
lights[0].enabled = !lights[0].enabled;
|
||||
}
|
||||
|
||||
// Update light values on shader (actually, only enable/disable them)
|
||||
for (&lights) |*l| {
|
||||
l.update(shader);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.black);
|
||||
{
|
||||
rl.beginMode3D(camera);
|
||||
defer rl.endMode3D();
|
||||
|
||||
// Set floor model texture tiling and emissive color parameters on shader
|
||||
rl.setShaderValue(shader, loc_texture_tiling, &floor_texture_tiling, .vec2);
|
||||
const floor_emissive_color: rl.Vector4 = rl.colorNormalize(floor.materials[0].maps[uMmi(.emission)].color);
|
||||
rl.setShaderValue(shader, loc_emissive_color, &floor_emissive_color, .vec4);
|
||||
|
||||
// Set floor metallic and roughness values
|
||||
rl.setShaderValue(shader, loc_metallic_value, &floor.materials[0].maps[uMmi(.metalness)].value, .float);
|
||||
rl.setShaderValue(shader, loc_roughness_value, &floor.materials[0].maps[uMmi(.roughness)].value, .float);
|
||||
|
||||
floor.draw(.init(0, 0, 0), 5, .white); // Draw floor model
|
||||
|
||||
// Set old car model texture tiling, emissive color and emissive intensity parameters on shader
|
||||
rl.setShaderValue(shader, loc_texture_tiling, &car_texture_tiling, .vec2);
|
||||
const car_emissive_color: rl.Vector4 = rl.colorNormalize(car.materials[0].maps[uMmi(.emission)].color);
|
||||
rl.setShaderValue(shader, loc_emissive_color, &car_emissive_color, .vec4);
|
||||
const emissive_intensity: f32 = 0.01;
|
||||
rl.setShaderValue(shader, loc_emissive_intensity, &emissive_intensity, .float);
|
||||
|
||||
// Set old car metallic and roughness values
|
||||
rl.setShaderValue(shader, loc_metallic_value, &car.materials[0].maps[uMmi(.metalness)].value, .float);
|
||||
rl.setShaderValue(shader, loc_roughness_value, &car.materials[0].maps[uMmi(.roughness)].value, .float);
|
||||
|
||||
car.draw(.init(0, 0, 0), 0.25, .white); // Draw car model
|
||||
|
||||
// Draw spheres to show the lights positions
|
||||
for (&lights) |*l| {
|
||||
const light_color: rl.Color = .init(
|
||||
@intFromFloat(l.color[0] * 255),
|
||||
@intFromFloat(l.color[1] * 255),
|
||||
@intFromFloat(l.color[2] * 255),
|
||||
@intFromFloat(l.color[3] * 255),
|
||||
);
|
||||
|
||||
if (l.enabled) {
|
||||
rl.drawSphereEx(l.position, 0.2, 8, 8, light_color);
|
||||
} else {
|
||||
rl.drawSphereWires(l.position, 0.2, 8, 8, rl.colorAlpha(light_color, 0.3));
|
||||
}
|
||||
}
|
||||
}
|
||||
rl.drawText("Toggle lights: [1][2][3][4]", 10, 40, 20, .light_gray);
|
||||
|
||||
rl.drawText("(c) Old Rusty Car model by Renafox (https://skfb.ly/LxRy)",
|
||||
screen_width - 320, screen_height - 20, 10, .light_gray);
|
||||
|
||||
rl.drawFPS(10, 10);
|
||||
}
|
||||
}
|
||||
197
examples/shaders/shaders_hybrid_render.zig
Normal file
@ -0,0 +1,197 @@
|
||||
// raylib [shaders] example - Hybrid Rendering
|
||||
//
|
||||
// Example complexity rating: [★★★★] 4/4
|
||||
//
|
||||
// Example originally created with raylib 4.2, last time updated with raylib 4.2
|
||||
//
|
||||
// Example contributed by Buğra Alptekin Sarı (@BugraAlptekinSari) 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) 2022-2025 Buğra Alptekin Sarı (@BugraAlptekinSari)
|
||||
|
||||
const rl = @import("raylib");
|
||||
const pi = @import("std").math.pi;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Declare custom Structs
|
||||
//------------------------------------------------------------------------------------
|
||||
|
||||
const RayLocs = struct {
|
||||
cam_pos: i32,
|
||||
cam_dir: i32,
|
||||
screen_center: i32,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.initWindow(screen_width, screen_height, "raylib [shaders] example - write depth buffer");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
|
||||
// This Shader calculates pixel depth and color using raymarch
|
||||
const shdr_raymarch: rl.Shader = try rl.loadShader(null, "resources/shaders/glsl330/hybrid_raymarch.fs");
|
||||
defer rl.unloadShader(shdr_raymarch);
|
||||
|
||||
// This Shader is a standard rasterization fragment shader with the addition of depth writing
|
||||
// You are required to write depth for all shaders if one shader does it
|
||||
const shdr_raster: rl.Shader = try rl.loadShader(null, "resources/shaders/glsl330/hybrid_raster.fs");
|
||||
defer rl.unloadShader(shdr_raster);
|
||||
|
||||
// Declare Struct used to store camera locs.
|
||||
const march_locs: RayLocs = .{
|
||||
.cam_pos = rl.getShaderLocation(shdr_raymarch, "camPos"),
|
||||
.cam_dir = rl.getShaderLocation(shdr_raymarch, "camDir"),
|
||||
.screen_center = rl.getShaderLocation(shdr_raymarch, "screenCenter"),
|
||||
};
|
||||
|
||||
// Transfer screenCenter position to shader. Which is used to calculate ray direction.
|
||||
const screen_center: rl.Vector2 = .init(screen_width / 2.0, screen_height / 2.0);
|
||||
rl.setShaderValue(shdr_raymarch, march_locs.screen_center , &screen_center , .vec2);
|
||||
|
||||
// Use Customized function to create writable depth texture buffer
|
||||
const target: rl.RenderTexture2D = try loadRenderTextureDepthTex(screen_width, screen_height);
|
||||
defer unloadRenderTextureDepthTex(target);
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
var camera: rl.Camera = .{
|
||||
.position = .init(0.5, 1, 1.5), // Camera position
|
||||
.target = .init(0, 0.5, 0), // Camera looking at point
|
||||
.up = .init(0, 1, 0), // Camera up vector (rotation towards target)
|
||||
.fovy = 45, // Camera field-of-view Y
|
||||
.projection = .perspective, // Camera projection type
|
||||
};
|
||||
|
||||
// Camera FOV is pre-calculated in the camera Distance.
|
||||
const cam_dist: f32 = 1.0 / @tan(camera.fovy * 0.5 * (pi / 180.0));
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
camera.update(.orbital);
|
||||
|
||||
// Update Camera Postion in the ray march shader.
|
||||
rl.setShaderValue(shdr_raymarch, march_locs.cam_pos, &camera.position, .vec3);
|
||||
|
||||
// Update Camera Looking Vector. Vector length determines FOV.
|
||||
const cam_dir: rl.Vector3 = .scale(.normalize(.subtract(camera.target, camera.position)), cam_dist);
|
||||
rl.setShaderValue(shdr_raymarch, march_locs.cam_dir, &cam_dir, .vec3);
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
// Draw into our custom render texture (framebuffer)
|
||||
{
|
||||
target.begin();
|
||||
defer target.end();
|
||||
|
||||
rl.clearBackground(.white);
|
||||
|
||||
// Raymarch Scene
|
||||
rl.gl.rlEnableDepthTest(); //Manually enable Depth Test to handle multiple rendering methods.
|
||||
{
|
||||
shdr_raymarch.activate();
|
||||
defer shdr_raymarch.deactivate();
|
||||
rl.drawRectangleRec(.init(0, 0, screen_width, screen_height), .white);
|
||||
}
|
||||
|
||||
// Rasterize Scene
|
||||
{
|
||||
rl.beginMode3D(camera);
|
||||
defer rl.endMode3D();
|
||||
|
||||
shdr_raster.activate();
|
||||
defer shdr_raster.deactivate();
|
||||
|
||||
rl.drawCubeWiresV(.init(0, 0.5, 1), .init(1, 1, 1), .red);
|
||||
rl.drawCubeV(.init(0, 0.5, 1), .init(1, 1, 1), .purple);
|
||||
rl.drawCubeWiresV(.init(0, 0.5, -1), .init(1, 1, 1), .dark_green);
|
||||
rl.drawCubeV(.init(0, 0.5, -1), .init(1, 1, 1), .yellow);
|
||||
rl.drawGrid(10, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Draw into screen our custom render texture
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
target.texture.drawRec(.init(0, 0, screen_width, -screen_height), .init(0, 0), .white);
|
||||
rl.drawFPS(10, 10);
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Define custom functions required for the example
|
||||
//------------------------------------------------------------------------------------
|
||||
// Load custom render texture, create a writable depth texture buffer
|
||||
fn loadRenderTextureDepthTex(width: i32, height: i32) !rl.RenderTexture2D {
|
||||
const id = rl.gl.rlLoadFramebuffer(); // Load an empty framebuffer
|
||||
if (id <= 0) {
|
||||
return error.LoadFrameBufferFail;
|
||||
}
|
||||
|
||||
rl.gl.rlEnableFramebuffer(id);
|
||||
defer rl.gl.rlDisableFramebuffer();
|
||||
|
||||
const pix_format: i32 = @intFromEnum(rl.gl.rlPixelFormat.rl_pixelformat_uncompressed_r8g8b8a8);
|
||||
|
||||
const target: rl.RenderTexture2D = .{
|
||||
.id = id,
|
||||
// Create color texture (default to RGBA)
|
||||
.texture = .{
|
||||
.id = rl.gl.rlLoadTexture(null, width, height, pix_format, 1),
|
||||
.width = width,
|
||||
.height = height,
|
||||
.format = .uncompressed_r8g8b8a8,
|
||||
.mipmaps = 1,
|
||||
},
|
||||
// Create depth texture buffer (instead of raylib default renderbuffer)
|
||||
.depth = .{
|
||||
.id = rl.gl.rlLoadTextureDepth(width, height, false),
|
||||
.width = width,
|
||||
.height = height,
|
||||
.format = .compressed_etc2_rgb, //DEPTH_COMPONENT_24BIT?
|
||||
.mipmaps = 1,
|
||||
}
|
||||
};
|
||||
|
||||
// Attach color texture and depth texture to FBO
|
||||
const channel0: i32 = @intFromEnum(rl.gl.rlFramebufferAttachType.rl_attachment_color_channel0);
|
||||
const depth: i32 = @intFromEnum(rl.gl.rlFramebufferAttachType.rl_attachment_depth);
|
||||
const texture2d: i32 = @intFromEnum(rl.gl.rlFramebufferAttachTextureType.rl_attachment_texture2d);
|
||||
rl.gl.rlFramebufferAttach(target.id, target.texture.id, channel0, texture2d, 0);
|
||||
rl.gl.rlFramebufferAttach(target.id, target.depth.id, depth, texture2d, 0);
|
||||
|
||||
// Check if fbo is complete with attachments (valid)
|
||||
if (rl.gl.rlFramebufferComplete(target.id)) {
|
||||
rl.traceLog(.info, "FBO: [ID %i] Framebuffer object created successfully", .{ target.id });
|
||||
}
|
||||
|
||||
return target;
|
||||
}
|
||||
|
||||
// Unload render texture from GPU memory (VRAM)
|
||||
fn unloadRenderTextureDepthTex(target: rl.RenderTexture2D) void {
|
||||
// Color texture attached to FBO is deleted
|
||||
rl.gl.rlUnloadTexture(target.texture.id);
|
||||
rl.gl.rlUnloadTexture(target.depth.id);
|
||||
|
||||
// NOTE: Depth texture is automatically
|
||||
// queried and deleted before deleting framebuffer
|
||||
rl.gl.rlUnloadFramebuffer(target.id);
|
||||
}
|
||||
@ -15,7 +15,7 @@ pub fn main() anyerror!void {
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib [shaders] example - Apply an outline to a texture");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
const texture: rl.Texture = try rl.Texture.init("resources/textures/fudesumi.png");
|
||||
const texture: rl.Texture = try .init("resources/textures/fudesumi.png");
|
||||
defer rl.unloadTexture(texture);
|
||||
|
||||
const shdrOutline: rl.Shader = try rl.loadShader(null, "resources/shaders/glsl330/outline.fs");
|
||||
@ -76,7 +76,7 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
{
|
||||
rl.beginShaderMode(shdrOutline);
|
||||
@ -85,18 +85,18 @@ pub fn main() anyerror!void {
|
||||
texture.draw(
|
||||
@divFloor(rl.getScreenWidth(), 2) - @divFloor(texture.width, 2),
|
||||
-30,
|
||||
rl.Color.white,
|
||||
.white,
|
||||
);
|
||||
}
|
||||
|
||||
rl.drawText("Shader-based\ntexture\noutline", 10, 10, 20, rl.Color.gray);
|
||||
rl.drawText("Shader-based\ntexture\noutline", 10, 10, 20, .gray);
|
||||
|
||||
rl.drawText(
|
||||
rl.textFormat("Outline size: %i px", .{@as(i32, @intFromFloat(outlineSize))}),
|
||||
10,
|
||||
120,
|
||||
20,
|
||||
rl.Color.maroon,
|
||||
.maroon,
|
||||
);
|
||||
|
||||
rl.drawFPS(710, 10);
|
||||
|
||||
@ -26,33 +26,33 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawText("some basic shapes available on raylib", 20, 20, 20, rl.Color.dark_gray);
|
||||
rl.drawText("some basic shapes available on raylib", 20, 20, 20, .dark_gray);
|
||||
|
||||
// Circle shapes and lines
|
||||
rl.drawCircle(screenWidth / 5, 120, 35, rl.Color.dark_blue);
|
||||
rl.drawCircleGradient(screenWidth / 5, 220, 60, rl.Color.green, rl.Color.sky_blue);
|
||||
rl.drawCircleLines(screenWidth / 5, 340, 80, rl.Color.dark_blue);
|
||||
rl.drawCircle(screenWidth / 5, 120, 35, .dark_blue);
|
||||
rl.drawCircleGradient(screenWidth / 5, 220, 60, .green, .sky_blue);
|
||||
rl.drawCircleLines(screenWidth / 5, 340, 80, .dark_blue);
|
||||
|
||||
// Rectangle shapes and lines
|
||||
rl.drawRectangle(screenWidth / 4 * 2 - 60, 100, 120, 60, rl.Color.red);
|
||||
rl.drawRectangleGradientH(screenWidth / 4 * 2 - 90, 170, 180, 130, rl.Color.maroon, rl.Color.gold);
|
||||
rl.drawRectangleLines(screenWidth / 4 * 2 - 40, 320, 80, 60, rl.Color.orange); // NOTE: Uses QUADS internally, not lines
|
||||
rl.drawRectangle(screenWidth / 4 * 2 - 60, 100, 120, 60, .red);
|
||||
rl.drawRectangleGradientH(screenWidth / 4 * 2 - 90, 170, 180, 130, .maroon, .gold);
|
||||
rl.drawRectangleLines(screenWidth / 4 * 2 - 40, 320, 80, 60, .orange); // NOTE: Uses QUADS internally, not lines
|
||||
|
||||
// Triangle shapes and lines
|
||||
rl.drawTriangle((rl.Vector2){ .x = (screenWidth / 4.0 * 3.0), .y = 80.0 }, (rl.Vector2){ .x = (screenWidth / 4.0 * 3.0 - 60.0), .y = 150.0 }, (rl.Vector2){ .x = (screenWidth / 4.0 * 3.0 + 60.0), .y = 150.0 }, rl.Color.violet);
|
||||
rl.drawTriangle(.{ .x = (screenWidth / 4.0 * 3.0), .y = 80.0 }, .{ .x = (screenWidth / 4.0 * 3.0 - 60.0), .y = 150.0 }, .{ .x = (screenWidth / 4.0 * 3.0 + 60.0), .y = 150.0 }, .violet);
|
||||
|
||||
rl.drawTriangleLines((rl.Vector2){ .x = (screenWidth / 4.0 * 3.0), .y = 160.0 }, (rl.Vector2){ .x = (screenWidth / 4.0 * 3.0 - 20.0), .y = 230.0 }, (rl.Vector2){ .x = (screenWidth / 4.0 * 3.0 + 20.0), .y = 230.0 }, rl.Color.dark_blue);
|
||||
rl.drawTriangleLines(.{ .x = (screenWidth / 4.0 * 3.0), .y = 160.0 }, .{ .x = (screenWidth / 4.0 * 3.0 - 20.0), .y = 230.0 }, .{ .x = (screenWidth / 4.0 * 3.0 + 20.0), .y = 230.0 }, .dark_blue);
|
||||
|
||||
// Polygon shapes and lines
|
||||
rl.drawPoly((rl.Vector2){ .x = (screenWidth / 4.0 * 3), .y = 330 }, 6, 80, rotation, rl.Color.brown);
|
||||
rl.drawPolyLines((rl.Vector2){ .x = (screenWidth / 4.0 * 3), .y = 330 }, 6, 90, rotation, rl.Color.brown);
|
||||
rl.drawPolyLinesEx((rl.Vector2){ .x = (screenWidth / 4.0 * 3), .y = 330 }, 6, 85, rotation, 6, rl.Color.beige);
|
||||
rl.drawPoly(.{ .x = (screenWidth / 4.0 * 3), .y = 330 }, 6, 80, rotation, .brown);
|
||||
rl.drawPolyLines(.{ .x = (screenWidth / 4.0 * 3), .y = 330 }, 6, 90, rotation, .brown);
|
||||
rl.drawPolyLinesEx(.{ .x = (screenWidth / 4.0 * 3), .y = 330 }, 6, 85, rotation, 6, .beige);
|
||||
|
||||
// NOTE: We draw all LINES based shapes together to optimize internal drawing,
|
||||
// this way, all LINES are rendered in a single draw pass
|
||||
rl.drawLine(18, 42, screenWidth - 18, 42, rl.Color.black);
|
||||
rl.drawLine(18, 42, screenWidth - 18, 42, .black);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -53,14 +53,14 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawCircleV(ballPosition, ballRadius, rl.Color.maroon);
|
||||
rl.drawText("PRESS SPACE to PAUSE BALL MOVEMENT", 10, rl.getScreenHeight() - 25, 20, rl.Color.light_gray);
|
||||
rl.drawCircleV(ballPosition, ballRadius, .maroon);
|
||||
rl.drawText("PRESS SPACE to PAUSE BALL MOVEMENT", 10, rl.getScreenHeight() - 25, 20, .light_gray);
|
||||
|
||||
// On pause, we draw a blinking message
|
||||
if (pause and @mod(@divFloor(framesCounter, 30), 2) == 0) {
|
||||
rl.drawText("PAUSED", 350, 200, 30, rl.Color.gray);
|
||||
rl.drawText("PAUSED", 350, 200, 30, .gray);
|
||||
}
|
||||
|
||||
rl.drawFPS(10, 10);
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
const rl = @import("raylib");
|
||||
|
||||
fn boxFmt(colliding: bool) rl.Color {
|
||||
if (colliding) return rl.Color.red;
|
||||
return rl.Color.black;
|
||||
if (colliding) return .red;
|
||||
return .black;
|
||||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
@ -83,12 +83,12 @@ pub fn main() anyerror!void {
|
||||
|
||||
rl.drawRectangle(0, 0, screenWidth, screenUpperLimit, boxFmt(collision));
|
||||
|
||||
rl.drawRectangleRec(boxA, rl.Color.gold);
|
||||
rl.drawRectangleRec(boxB, rl.Color.blue);
|
||||
rl.drawRectangleRec(boxA, .gold);
|
||||
rl.drawRectangleRec(boxB, .blue);
|
||||
|
||||
if (collision) {
|
||||
// Draw collision area
|
||||
rl.drawRectangleRec(boxCollision, rl.Color.lime);
|
||||
rl.drawRectangleRec(boxCollision, .lime);
|
||||
|
||||
// Draw collision message
|
||||
rl.drawText(
|
||||
@ -96,19 +96,19 @@ pub fn main() anyerror!void {
|
||||
@divFloor(rl.getScreenWidth(), @as(i32, 2)) - @divFloor(rl.measureText("COLLISION!", 20), @as(i32, 2)),
|
||||
screenUpperLimit / 2 - 10,
|
||||
20,
|
||||
rl.Color.black,
|
||||
.black,
|
||||
);
|
||||
|
||||
// Draw collision area
|
||||
rl.drawText(rl.textFormat("Collision Area: %i", .{@as(i32, @intFromFloat(boxCollision.width * boxCollision.height))}), @divFloor(rl.getScreenWidth(), 2) - 100, screenUpperLimit + 10, 20, rl.Color.black);
|
||||
rl.drawText(rl.textFormat("Collision Area: %i", .{@as(i32, @intFromFloat(boxCollision.width * boxCollision.height))}), @divFloor(rl.getScreenWidth(), 2) - 100, screenUpperLimit + 10, 20, .black);
|
||||
}
|
||||
|
||||
// Draw help instructions
|
||||
rl.drawText("Press SPACE to PAUSE/RESUME", 20, screenHeight - 35, 20, rl.Color.light_gray);
|
||||
rl.drawText("Press SPACE to PAUSE/RESUME", 20, screenHeight - 35, 20, .light_gray);
|
||||
|
||||
rl.drawFPS(10, 10);
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,27 +20,27 @@ pub fn main() anyerror!void {
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
const colors = [maxColorCount]rl.Color{
|
||||
rl.Color.dark_gray,
|
||||
rl.Color.maroon,
|
||||
rl.Color.orange,
|
||||
rl.Color.dark_green,
|
||||
rl.Color.dark_blue,
|
||||
rl.Color.dark_purple,
|
||||
rl.Color.dark_brown,
|
||||
rl.Color.gray,
|
||||
rl.Color.red,
|
||||
rl.Color.gold,
|
||||
rl.Color.lime,
|
||||
rl.Color.blue,
|
||||
rl.Color.violet,
|
||||
rl.Color.brown,
|
||||
rl.Color.light_gray,
|
||||
rl.Color.pink,
|
||||
rl.Color.yellow,
|
||||
rl.Color.green,
|
||||
rl.Color.sky_blue,
|
||||
rl.Color.purple,
|
||||
rl.Color.beige,
|
||||
.dark_gray,
|
||||
.maroon,
|
||||
.orange,
|
||||
.dark_green,
|
||||
.dark_blue,
|
||||
.dark_purple,
|
||||
.dark_brown,
|
||||
.gray,
|
||||
.red,
|
||||
.gold,
|
||||
.lime,
|
||||
.blue,
|
||||
.violet,
|
||||
.brown,
|
||||
.light_gray,
|
||||
.pink,
|
||||
.yellow,
|
||||
.green,
|
||||
.sky_blue,
|
||||
.purple,
|
||||
.beige,
|
||||
};
|
||||
|
||||
const colorNames = [maxColorCount][:0]const u8{
|
||||
@ -105,18 +105,18 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawText("raylib colors palette", 28, 42, 20, rl.Color.black);
|
||||
rl.drawText("press SPACE to see all colors", rl.getScreenWidth() - 180, rl.getScreenHeight() - 40, 10, rl.Color.gray);
|
||||
rl.drawText("raylib colors palette", 28, 42, 20, .black);
|
||||
rl.drawText("press SPACE to see all colors", rl.getScreenWidth() - 180, rl.getScreenHeight() - 40, 10, .gray);
|
||||
|
||||
i = 0;
|
||||
while (i < maxColorCount) : (i += 1) {
|
||||
rl.drawRectangleRec(colorsRecs[i], rl.fade(colors[i], getAlpha(colorState[i])));
|
||||
rl.drawRectangleRec(colorsRecs[i], .fade(colors[i], getAlpha(colorState[i])));
|
||||
|
||||
if (rl.isKeyDown(.space) or colorState[i]) {
|
||||
rl.drawRectangle(@intFromFloat(colorsRecs[i].x), @as(i32, @intFromFloat(colorsRecs[i].y)) + @as(i32, @intFromFloat(colorsRecs[i].height)) - 26, @as(i32, @intFromFloat(colorsRecs[i].width)), 20, rl.Color.black);
|
||||
rl.drawRectangleLinesEx(colorsRecs[i], 6, rl.fade(rl.Color.black, 0.3));
|
||||
rl.drawRectangle(@intFromFloat(colorsRecs[i].x), @as(i32, @intFromFloat(colorsRecs[i].y)) + @as(i32, @intFromFloat(colorsRecs[i].height)) - 26, @as(i32, @intFromFloat(colorsRecs[i].width)), 20, .black);
|
||||
rl.drawRectangleLinesEx(colorsRecs[i], 6, .fade(.black, 0.3));
|
||||
|
||||
rl.drawText(colorNames[i], @as(i32, @intFromFloat(colorsRecs[i].x)) + @as(i32, @intFromFloat(colorsRecs[i].width)) - rl.measureText(colorNames[i], 10) - 12, @as(i32, @intFromFloat(colorsRecs[i].y)) + @as(i32, @intFromFloat(colorsRecs[i].height)) - 20, 10, colors[i]);
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@ fn labelFmt(segments: f32, minSegments: f32) [*c]const u8 {
|
||||
}
|
||||
|
||||
fn colorFmt(segments: f32, minSegments: f32) rl.Color {
|
||||
if (segments >= minSegments) return rl.Color.maroon;
|
||||
return rl.Color.dark_gray;
|
||||
if (segments >= minSegments) return .maroon;
|
||||
return .dark_gray;
|
||||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
@ -45,20 +45,20 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawLine(500, 0, 500, rl.getScreenHeight(), rl.fade(rl.Color.light_gray, 0.6));
|
||||
rl.drawRectangle(500, 0, rl.getScreenWidth() - 500, rl.getScreenHeight(), rl.fade(rl.Color.light_gray, 0.3));
|
||||
rl.drawLine(500, 0, 500, rl.getScreenHeight(), .fade(.light_gray, 0.6));
|
||||
rl.drawRectangle(500, 0, rl.getScreenWidth() - 500, rl.getScreenHeight(), .fade(.light_gray, 0.3));
|
||||
|
||||
rl.drawCircleSector(center, outerRadius, startAngle, endAngle, @as(i32, @intFromFloat(segments)), rl.fade(rl.Color.maroon, 0.3));
|
||||
rl.drawCircleSectorLines(center, outerRadius, startAngle, endAngle, @as(i32, @intFromFloat(segments)), rl.fade(rl.Color.maroon, 0.6));
|
||||
rl.drawCircleSector(center, outerRadius, startAngle, endAngle, @as(i32, @intFromFloat(segments)), .fade(.maroon, 0.3));
|
||||
rl.drawCircleSectorLines(center, outerRadius, startAngle, endAngle, @as(i32, @intFromFloat(segments)), .fade(.maroon, 0.6));
|
||||
|
||||
// Draw GUI controls
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 600, .y = 40, .width = 120, .height = 20 }, "StartAngle", rl.textFormat("%.2", .{startAngle}), &startAngle, 0, 720);
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 600, .y = 70, .width = 120, .height = 20 }, "EndAngle", rl.textFormat("%.2", .{endAngle}), &endAngle, 0, 720);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 600, .y = 40, .width = 120, .height = 20 }, "StartAngle", rl.textFormat("%.2", .{startAngle}), &startAngle, 0, 720);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 600, .y = 70, .width = 120, .height = 20 }, "EndAngle", rl.textFormat("%.2", .{endAngle}), &endAngle, 0, 720);
|
||||
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 600, .y = 140, .width = 120, .height = 20 }, "Radius", rl.textFormat("%.2", .{outerRadius}), &outerRadius, 0, 200);
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 600, .y = 170, .width = 120, .height = 20 }, "Segments", rl.textFormat("%.2", .{segments}), &segments, 0, 100);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 600, .y = 140, .width = 120, .height = 20 }, "Radius", rl.textFormat("%.2", .{outerRadius}), &outerRadius, 0, 200);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 600, .y = 170, .width = 120, .height = 20 }, "Segments", rl.textFormat("%.2", .{segments}), &segments, 0, 100);
|
||||
|
||||
minSegments = math.trunc(math.ceil((endAngle - startAngle) / 90));
|
||||
rl.drawText(rl.textFormat("MODE: %s", .{labelFmt(segments, minSegments)}), 600, 200, 10, colorFmt(segments, minSegments));
|
||||
|
||||
@ -7,8 +7,8 @@ fn labelFmt(segments: f32) [*c]const u8 {
|
||||
}
|
||||
|
||||
fn colorFmt(segments: f32) rl.Color {
|
||||
if (segments >= 4) return rl.Color.maroon;
|
||||
return rl.Color.dark_gray;
|
||||
if (segments >= 4) return .maroon;
|
||||
return .dark_gray;
|
||||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
@ -45,25 +45,25 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawLine(560, 0, 560, rl.getScreenHeight(), rl.fade(rl.Color.light_gray, 0.6));
|
||||
rl.drawRectangle(560, 0, rl.getScreenWidth() - 500, rl.getScreenHeight(), rl.fade(rl.Color.light_gray, 0.3));
|
||||
rl.drawLine(560, 0, 560, rl.getScreenHeight(), .fade(.light_gray, 0.6));
|
||||
rl.drawRectangle(560, 0, rl.getScreenWidth() - 500, rl.getScreenHeight(), .fade(.light_gray, 0.3));
|
||||
|
||||
if (drawRect) rl.drawRectangleRec(rec, rl.fade(rl.Color.gold, 0.6));
|
||||
if (drawRoundedRect) rl.drawRectangleRounded(rec, roundness, @as(i32, @intFromFloat(segments)), rl.fade(rl.Color.maroon, 0.2));
|
||||
if (drawRoundedLines) rl.drawRectangleRoundedLinesEx(rec, roundness, @as(i32, @intFromFloat(segments)), lineThick, rl.fade(rl.Color.maroon, 0.4));
|
||||
if (drawRect) rl.drawRectangleRec(rec, .fade(.gold, 0.6));
|
||||
if (drawRoundedRect) rl.drawRectangleRounded(rec, roundness, @as(i32, @intFromFloat(segments)), .fade(.maroon, 0.2));
|
||||
if (drawRoundedLines) rl.drawRectangleRoundedLinesEx(rec, roundness, @as(i32, @intFromFloat(segments)), lineThick, .fade(.maroon, 0.4));
|
||||
|
||||
// Draw GUI controls
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 640, .y = 40, .width = 105, .height = 20 }, "Width", rl.textFormat("%.2", .{width}), &width, 0, @as(f32, @floatFromInt(rl.getScreenWidth() - 300)));
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 640, .y = 70, .width = 105, .height = 20 }, "Height", rl.textFormat("%.2", .{height}), &height, 0, @as(f32, @floatFromInt(rl.getScreenHeight() - 50)));
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 640, .y = 140, .width = 105, .height = 20 }, "Roundness", rl.textFormat("%.2", .{roundness}), &roundness, 0.0, 1.0);
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 640, .y = 170, .width = 105, .height = 20 }, "Thickness", rl.textFormat("%.2", .{lineThick}), &lineThick, 0, 20);
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 640, .y = 240, .width = 105, .height = 20 }, "Segments", rl.textFormat("%.2", .{segments}), &segments, 0, 60);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 640, .y = 40, .width = 105, .height = 20 }, "Width", rl.textFormat("%.2", .{width}), &width, 0, @as(f32, @floatFromInt(rl.getScreenWidth() - 300)));
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 640, .y = 70, .width = 105, .height = 20 }, "Height", rl.textFormat("%.2", .{height}), &height, 0, @as(f32, @floatFromInt(rl.getScreenHeight() - 50)));
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 640, .y = 140, .width = 105, .height = 20 }, "Roundness", rl.textFormat("%.2", .{roundness}), &roundness, 0.0, 1.0);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 640, .y = 170, .width = 105, .height = 20 }, "Thickness", rl.textFormat("%.2", .{lineThick}), &lineThick, 0, 20);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 640, .y = 240, .width = 105, .height = 20 }, "Segments", rl.textFormat("%.2", .{segments}), &segments, 0, 60);
|
||||
|
||||
_ = rgui.guiCheckBox(rl.Rectangle{ .x = 640, .y = 320, .width = 20, .height = 20 }, "DrawRoundedRect", &drawRoundedRect);
|
||||
_ = rgui.guiCheckBox(rl.Rectangle{ .x = 640, .y = 350, .width = 20, .height = 20 }, "DrawRoundedLines", &drawRoundedLines);
|
||||
_ = rgui.guiCheckBox(rl.Rectangle{ .x = 640, .y = 380, .width = 20, .height = 20 }, "DrawRect", &drawRect);
|
||||
_ = rgui.checkBox(rl.Rectangle{ .x = 640, .y = 320, .width = 20, .height = 20 }, "DrawRoundedRect", &drawRoundedRect);
|
||||
_ = rgui.checkBox(rl.Rectangle{ .x = 640, .y = 350, .width = 20, .height = 20 }, "DrawRoundedLines", &drawRoundedLines);
|
||||
_ = rgui.checkBox(rl.Rectangle{ .x = 640, .y = 380, .width = 20, .height = 20 }, "DrawRect", &drawRect);
|
||||
|
||||
rl.drawText(rl.textFormat("MODE: %s", .{labelFmt(segments)}), 640, 280, 10, colorFmt(segments));
|
||||
|
||||
|
||||
@ -9,8 +9,8 @@ fn labelFmt(segments: f32, minSegments: f32) [*c]const u8 {
|
||||
}
|
||||
|
||||
fn colorFmt(segments: f32, minSegments: f32) rl.Color {
|
||||
if (segments >= minSegments) return rl.Color.maroon;
|
||||
return rl.Color.dark_gray;
|
||||
if (segments >= minSegments) return .maroon;
|
||||
return .dark_gray;
|
||||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
@ -50,28 +50,28 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawLine(500, 0, 500, rl.getScreenHeight(), rl.fade(rl.Color.light_gray, 0.6));
|
||||
rl.drawRectangle(500, 0, rl.getScreenWidth() - 500, rl.getScreenHeight(), rl.fade(rl.Color.light_gray, 0.3));
|
||||
rl.drawLine(500, 0, 500, rl.getScreenHeight(), .fade(.light_gray, 0.6));
|
||||
rl.drawRectangle(500, 0, rl.getScreenWidth() - 500, rl.getScreenHeight(), .fade(.light_gray, 0.3));
|
||||
|
||||
if (drawRing) rl.drawRing(center, innerRadius, outerRadius, startAngle, endAngle, @intFromFloat(segments), rl.fade(rl.Color.maroon, 0.3));
|
||||
if (drawRingLines) rl.drawRingLines(center, innerRadius, outerRadius, startAngle, endAngle, @intFromFloat(segments), rl.fade(rl.Color.black, 0.4));
|
||||
if (drawCircleLines) rl.drawCircleSectorLines(center, outerRadius, startAngle, endAngle, @intFromFloat(segments), rl.fade(rl.Color.black, 0.4));
|
||||
if (drawRing) rl.drawRing(center, innerRadius, outerRadius, startAngle, endAngle, @intFromFloat(segments), .fade(.maroon, 0.3));
|
||||
if (drawRingLines) rl.drawRingLines(center, innerRadius, outerRadius, startAngle, endAngle, @intFromFloat(segments), .fade(.black, 0.4));
|
||||
if (drawCircleLines) rl.drawCircleSectorLines(center, outerRadius, startAngle, endAngle, @intFromFloat(segments), .fade(.black, 0.4));
|
||||
|
||||
// Draw GUI controls
|
||||
//------------------------------------------------------------------------------
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 600, .y = 40, .width = 120, .height = 20 }, "StartAngle", rl.textFormat("%.2", .{startAngle}), &startAngle, -450, 450);
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 600, .y = 70, .width = 120, .height = 20 }, "EndAngle", rl.textFormat("%.2", .{endAngle}), &endAngle, -450, 450);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 600, .y = 40, .width = 120, .height = 20 }, "StartAngle", rl.textFormat("%.2", .{startAngle}), &startAngle, -450, 450);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 600, .y = 70, .width = 120, .height = 20 }, "EndAngle", rl.textFormat("%.2", .{endAngle}), &endAngle, -450, 450);
|
||||
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 600, .y = 140, .width = 120, .height = 20 }, "InnerRadius", rl.textFormat("%.2", .{innerRadius}), &innerRadius, 0, 100);
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 600, .y = 170, .width = 120, .height = 20 }, "OuterRadius", rl.textFormat("%.2", .{outerRadius}), &outerRadius, 0, 200);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 600, .y = 140, .width = 120, .height = 20 }, "InnerRadius", rl.textFormat("%.2", .{innerRadius}), &innerRadius, 0, 100);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 600, .y = 170, .width = 120, .height = 20 }, "OuterRadius", rl.textFormat("%.2", .{outerRadius}), &outerRadius, 0, 200);
|
||||
|
||||
_ = rgui.guiSliderBar(rl.Rectangle{ .x = 600, .y = 240, .width = 120, .height = 20 }, "Segments", rl.textFormat("%.2", .{segments}), &segments, 0, 100);
|
||||
_ = rgui.sliderBar(rl.Rectangle{ .x = 600, .y = 240, .width = 120, .height = 20 }, "Segments", rl.textFormat("%.2", .{segments}), &segments, 0, 100);
|
||||
|
||||
_ = rgui.guiCheckBox(rl.Rectangle{ .x = 600, .y = 320, .width = 20, .height = 20 }, "Draw Ring", &drawRing);
|
||||
_ = rgui.guiCheckBox(rl.Rectangle{ .x = 600, .y = 350, .width = 20, .height = 20 }, "Draw RingLines", &drawRingLines);
|
||||
_ = rgui.guiCheckBox(rl.Rectangle{ .x = 600, .y = 380, .width = 20, .height = 20 }, "Draw CircleLines", &drawCircleLines);
|
||||
_ = rgui.checkBox(rl.Rectangle{ .x = 600, .y = 320, .width = 20, .height = 20 }, "Draw Ring", &drawRing);
|
||||
_ = rgui.checkBox(rl.Rectangle{ .x = 600, .y = 350, .width = 20, .height = 20 }, "Draw RingLines", &drawRingLines);
|
||||
_ = rgui.checkBox(rl.Rectangle{ .x = 600, .y = 380, .width = 20, .height = 20 }, "Draw CircleLines", &drawCircleLines);
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const minSegments: f32 = math.ceil((endAngle - startAngle) / 90);
|
||||
|
||||
86
examples/shapes/easings_ball_anim.zig
Normal file
@ -0,0 +1,86 @@
|
||||
const rl = @import("raylib");
|
||||
const reasings = @import("reasings.zig");
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screenWidth = 800;
|
||||
const screenHeight = 450;
|
||||
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib [shapes] example - easings ball anim");
|
||||
defer rl.closeWindow(); // Defer closing window and OpenGL context
|
||||
|
||||
// Ball variable value to be animated with easings
|
||||
var ballPositionX: i32 = -100;
|
||||
var ballRadius: f32 = 20;
|
||||
var ballAlpha: f32 = 0;
|
||||
|
||||
var state: i32 = 0;
|
||||
var framesCounter: i32 = 0;
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
switch (state) {
|
||||
0 => { // Move ball position X with easing
|
||||
framesCounter += 1;
|
||||
ballPositionX = @intFromFloat(reasings.elasticOut(@floatFromInt(framesCounter), -100, @as(f32, @floatFromInt(screenWidth)) / 2 + 100, 120));
|
||||
|
||||
if (framesCounter >= 120) {
|
||||
framesCounter = 0;
|
||||
state = 1;
|
||||
}
|
||||
},
|
||||
1 => { // Increase ball radius with easing
|
||||
framesCounter += 1;
|
||||
ballRadius = reasings.elasticIn(@floatFromInt(framesCounter), 20, 500, 200);
|
||||
|
||||
if (framesCounter >= 200) {
|
||||
framesCounter = 0;
|
||||
state = 2;
|
||||
}
|
||||
},
|
||||
2 => { // Change ball alpha with easing (background color blending)
|
||||
framesCounter += 1;
|
||||
ballAlpha = reasings.cubicOut(@floatFromInt(framesCounter), 0.0, 1.0, 200);
|
||||
if (framesCounter >= 200) {
|
||||
framesCounter = 0;
|
||||
state = 3;
|
||||
}
|
||||
},
|
||||
3 => { // Reset state to play again
|
||||
if (rl.isKeyPressed(.enter)) {
|
||||
ballPositionX = -100;
|
||||
ballRadius = 20;
|
||||
ballAlpha = 0.0;
|
||||
state = 0;
|
||||
}
|
||||
},
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
if (rl.isKeyPressed(.r)) framesCounter = 0;
|
||||
//----------------------------------------------------------------------------------
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
if (state >= 2) rl.drawRectangle(0, 0, screenWidth, screenHeight, .green);
|
||||
rl.drawCircle(ballPositionX, 200, ballRadius, .fade(.red, 1.0 - ballAlpha));
|
||||
|
||||
if (state == 3) rl.drawText("PRESS [ENTER] TO PLAY AGAIN!", 240, 200, 20, .black);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
127
examples/shapes/easings_box_anim.zig
Normal file
@ -0,0 +1,127 @@
|
||||
const rl = @import("raylib");
|
||||
const reasing = @import("reasings.zig");
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screenWidth = 800;
|
||||
const screenHeight = 450;
|
||||
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib [shapes] example - easings box anim");
|
||||
defer rl.closeWindow();
|
||||
|
||||
// Box variables to be animated with easings
|
||||
var rec: rl.Rectangle = rl.Rectangle{
|
||||
.x = @as(f32, @floatFromInt(rl.getScreenWidth())) / 2.0,
|
||||
.y = -100,
|
||||
.height = 100,
|
||||
.width = 100,
|
||||
};
|
||||
var rotation: f32 = 0.0;
|
||||
var alpha: f32 = 1.0;
|
||||
|
||||
var state: i32 = 0;
|
||||
var framesCounter: i32 = 0;
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
switch (state) {
|
||||
// Move box down to center of screen
|
||||
0 => {
|
||||
framesCounter += 1;
|
||||
|
||||
// NOTE: Remember that 3rd parameter of easing function refers to
|
||||
// desired value variation, do not confuse it with expected final value!
|
||||
rec.y = reasing.elasticOut(@floatFromInt(framesCounter), -100, @as(f32, @floatFromInt(rl.getScreenHeight())) / 2.0 + 100, 120);
|
||||
|
||||
if (framesCounter >= 120) {
|
||||
framesCounter = 0;
|
||||
state = 1;
|
||||
}
|
||||
},
|
||||
// Scale box to an horizontal bar
|
||||
1 => {
|
||||
framesCounter += 1;
|
||||
rec.height = reasing.bounceOut(@floatFromInt(framesCounter), 100, -90, 120);
|
||||
rec.width = reasing.bounceOut(@floatFromInt(framesCounter), 100, @floatFromInt(rl.getScreenWidth()), 120);
|
||||
|
||||
if (framesCounter >= 120) {
|
||||
framesCounter = 0;
|
||||
state = 2;
|
||||
}
|
||||
},
|
||||
// Rotate horizontal bar rectangle
|
||||
2 => {
|
||||
framesCounter += 1;
|
||||
rotation = reasing.quadOut(@floatFromInt(framesCounter), 0.0, 270.0, 240);
|
||||
|
||||
if (framesCounter >= 240) {
|
||||
framesCounter = 0;
|
||||
state = 3;
|
||||
}
|
||||
},
|
||||
// Increase bar size to fill all screen
|
||||
3 => {
|
||||
framesCounter += 1;
|
||||
rec.height = reasing.circOut(@floatFromInt(framesCounter), 10, @floatFromInt(rl.getScreenWidth()), 120);
|
||||
|
||||
if (framesCounter >= 120) {
|
||||
framesCounter = 0;
|
||||
state = 4;
|
||||
}
|
||||
},
|
||||
// Fade out animation
|
||||
4 => {
|
||||
framesCounter += 1;
|
||||
alpha = reasing.sineOut(@floatFromInt(framesCounter), 1.0, -1.0, 160);
|
||||
|
||||
if (framesCounter >= 160) {
|
||||
framesCounter = 0;
|
||||
state = 5;
|
||||
}
|
||||
},
|
||||
5 => {},
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
// Reset animation at any moment
|
||||
if (rl.isKeyPressed(.space)) {
|
||||
rec = rl.Rectangle{
|
||||
.x = @as(f32, @floatFromInt(rl.getScreenWidth())) / 2.0,
|
||||
.y = -100,
|
||||
.height = 100,
|
||||
.width = 100,
|
||||
};
|
||||
rotation = 0.0;
|
||||
alpha = 1.0;
|
||||
state = 0;
|
||||
framesCounter = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawRectanglePro(rec, rl.Vector2{
|
||||
.x = rec.width / 2,
|
||||
.y = rec.height / 2,
|
||||
}, rotation, .fade(.black, alpha));
|
||||
|
||||
rl.drawText("PRESS [SPACE] TO RESET BOX ANIMATION!", 10, rl.getScreenHeight() - 25, 20, .light_gray);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
91
examples/shapes/easings_rectangle_array.zig
Normal file
@ -0,0 +1,91 @@
|
||||
const rl = @import("raylib");
|
||||
const reasings = @import("reasings.zig");
|
||||
|
||||
const RECS_WIDTH = 50;
|
||||
const RECS_HEIGHT = 50;
|
||||
const SCREEN_WIDTH = 800;
|
||||
const SCREEN_HEIGHT = 450;
|
||||
|
||||
const MAX_RECS_X = SCREEN_WIDTH / RECS_WIDTH;
|
||||
const MAX_RECS_Y = SCREEN_HEIGHT / RECS_HEIGHT;
|
||||
|
||||
const PLAY_TIME_IN_FRAMES = 240; // At 60 fps = 4 seconds
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
rl.initWindow(SCREEN_WIDTH, SCREEN_HEIGHT, "raylib [shapes] example - easings rectangle array");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
var recs: [MAX_RECS_X * MAX_RECS_Y]rl.Rectangle = undefined;
|
||||
|
||||
for (0..MAX_RECS_Y) |y| {
|
||||
for (0..MAX_RECS_X) |x| {
|
||||
recs[y * MAX_RECS_X + x].x = RECS_WIDTH / 2.0 + RECS_WIDTH * @as(f32, @floatFromInt(x));
|
||||
recs[y * MAX_RECS_X + x].y = RECS_HEIGHT / 2.0 + RECS_HEIGHT * @as(f32, @floatFromInt(y));
|
||||
recs[y * MAX_RECS_X + x].width = RECS_WIDTH;
|
||||
recs[y * MAX_RECS_X + x].height = RECS_HEIGHT;
|
||||
}
|
||||
}
|
||||
|
||||
var rotation: f32 = 0.0;
|
||||
var framesCounter: i32 = 0;
|
||||
var state: i32 = 0; // Rectangles animation state: 0-Playing, 1-Finished
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (state == 0) {
|
||||
framesCounter += 1;
|
||||
|
||||
for (&recs) |*rec| {
|
||||
rec.height = reasings.circOut(@floatFromInt(framesCounter), RECS_HEIGHT, -RECS_HEIGHT, PLAY_TIME_IN_FRAMES);
|
||||
rec.width = reasings.circOut(@floatFromInt(framesCounter), RECS_WIDTH, -RECS_WIDTH, PLAY_TIME_IN_FRAMES);
|
||||
|
||||
if (rec.height < 0) rec.height = 0;
|
||||
if (rec.width < 0) rec.width = 0;
|
||||
|
||||
if ((rec.height == 0) and (rec.width == 0)) state = 1; // Finish playing
|
||||
|
||||
rotation = reasings.linearIn(@floatFromInt(framesCounter), 0.0, 360.0, PLAY_TIME_IN_FRAMES);
|
||||
}
|
||||
} else if ((state == 1) and rl.isKeyPressed(.space)) {
|
||||
// When animation has finished, press space to restart
|
||||
framesCounter = 0;
|
||||
|
||||
for (&recs) |*rec| {
|
||||
rec.height = RECS_HEIGHT;
|
||||
rec.width = RECS_WIDTH;
|
||||
}
|
||||
|
||||
state = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
if (state == 0) {
|
||||
for (recs) |rec| {
|
||||
rl.drawRectanglePro(rec, rl.Vector2{
|
||||
.x = rec.width / 2,
|
||||
.y = rec.height / 2,
|
||||
}, rotation, .red);
|
||||
}
|
||||
} else if (state == 1) rl.drawText("PRESS [SPACE] TO PLAY AGAIN!", 240, 200, 20, .gray);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
@ -69,17 +69,17 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.drawCircleV(scleraLeftPosition, scleraRadius, rl.Color.light_gray);
|
||||
rl.drawCircleV(irisLeftPosition, irisRadius, rl.Color.brown);
|
||||
rl.drawCircleV(irisLeftPosition, 10, rl.Color.black);
|
||||
rl.drawCircleV(scleraLeftPosition, scleraRadius, .light_gray);
|
||||
rl.drawCircleV(irisLeftPosition, irisRadius, .brown);
|
||||
rl.drawCircleV(irisLeftPosition, 10, .black);
|
||||
|
||||
rl.drawCircleV(scleraRightPosition, scleraRadius, rl.Color.light_gray);
|
||||
rl.drawCircleV(irisRightPosition, irisRadius, rl.Color.dark_green);
|
||||
rl.drawCircleV(irisRightPosition, 10, rl.Color.black);
|
||||
rl.drawCircleV(scleraRightPosition, scleraRadius, .light_gray);
|
||||
rl.drawCircleV(irisRightPosition, irisRadius, .dark_green);
|
||||
rl.drawCircleV(irisRightPosition, 10, .black);
|
||||
|
||||
rl.drawFPS(10, 10);
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,8 +6,8 @@ fn collisionFmt(isColliding: bool) f32 {
|
||||
}
|
||||
|
||||
fn movingFmt(isMoving: bool) rl.Color {
|
||||
if (isMoving) return rl.Color.red;
|
||||
return rl.Color.blue;
|
||||
if (isMoving) return .red;
|
||||
return .blue;
|
||||
}
|
||||
|
||||
pub fn main() anyerror!void {
|
||||
@ -60,12 +60,12 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawText("MOVE START-END POINTS WITH MOUSE", 15, 20, 20, rl.Color.gray);
|
||||
rl.drawText("MOVE START-END POINTS WITH MOUSE", 15, 20, 20, .gray);
|
||||
|
||||
// Draw line Cubic Bezier, in-out interpolation (easing), no control points
|
||||
rl.drawLineBezier(startPoint, endPoint, 4.0, rl.Color.blue);
|
||||
rl.drawLineBezier(startPoint, endPoint, 4.0, .blue);
|
||||
|
||||
// Draw start-end spline circles with some details
|
||||
rl.drawCircleV(startPoint, collisionFmt(rl.checkCollisionPointCircle(mouse, startPoint, 10.0)), movingFmt(moveStartPoint));
|
||||
|
||||
@ -28,13 +28,13 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawRectangle(screenWidth / 2 - 128, screenHeight / 2 - 128, 256, 256, raylib_zig);
|
||||
rl.drawRectangle(screenWidth / 2 - 112, screenHeight / 2 - 112, 224, 224, rl.Color.ray_white);
|
||||
rl.drawRectangle(screenWidth / 2 - 112, screenHeight / 2 - 112, 224, 224, .ray_white);
|
||||
rl.drawText("raylib-zig", screenWidth / 2 - 96, screenHeight / 2 + 57, 41, raylib_zig);
|
||||
|
||||
rl.drawText("this is NOT a texture!", 350, 370, 10, rl.Color.gray);
|
||||
rl.drawText("this is NOT a texture!", 350, 370, 10, .gray);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
@ -90,37 +90,37 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
if (state == 0) {
|
||||
if (@mod(framesCounter, @as(u8, 15)) == 0) rl.drawRectangle(logoPositionX, logoPositionY, 16, 16, rl.Color.black);
|
||||
if (@mod(framesCounter, @as(u8, 15)) == 0) rl.drawRectangle(logoPositionX, logoPositionY, 16, 16, .black);
|
||||
} else if (state == 1) {
|
||||
rl.drawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, rl.Color.black);
|
||||
rl.drawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, rl.Color.black);
|
||||
rl.drawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, .black);
|
||||
rl.drawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, .black);
|
||||
} else if (state == 2) {
|
||||
rl.drawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, rl.Color.black);
|
||||
rl.drawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, rl.Color.black);
|
||||
rl.drawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, .black);
|
||||
rl.drawRectangle(logoPositionX, logoPositionY, 16, leftSideRecHeight, .black);
|
||||
|
||||
rl.drawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, rl.Color.black);
|
||||
rl.drawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, rl.Color.black);
|
||||
rl.drawRectangle(logoPositionX + 240, logoPositionY, 16, rightSideRecHeight, .black);
|
||||
rl.drawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, .black);
|
||||
} else if (state == 3) {
|
||||
rl.drawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, rl.fade(rl.Color.black, alpha));
|
||||
rl.drawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, rl.fade(rl.Color.black, alpha));
|
||||
rl.drawRectangle(logoPositionX, logoPositionY, topSideRecWidth, 16, .fade(.black, alpha));
|
||||
rl.drawRectangle(logoPositionX, logoPositionY + 16, 16, leftSideRecHeight - 32, .fade(.black, alpha));
|
||||
|
||||
rl.drawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, rl.fade(rl.Color.black, alpha));
|
||||
rl.drawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, rl.fade(rl.Color.black, alpha));
|
||||
rl.drawRectangle(logoPositionX + 240, logoPositionY + 16, 16, rightSideRecHeight - 32, .fade(.black, alpha));
|
||||
rl.drawRectangle(logoPositionX, logoPositionY + 240, bottomSideRecWidth, 16, .fade(.black, alpha));
|
||||
|
||||
rl.drawRectangle(
|
||||
(@divFloor(rl.getScreenWidth(), @as(i32, 2))) - 112,
|
||||
(@divFloor(rl.getScreenHeight(), @as(i32, 2))) - 112,
|
||||
224,
|
||||
224,
|
||||
rl.fade(rl.Color.ray_white, alpha),
|
||||
.fade(.ray_white, alpha),
|
||||
);
|
||||
|
||||
rl.drawText(rl.textSubtext("raylib", 0, lettersCount), @divFloor(rl.getScreenWidth(), @as(i32, 2)) - 44, @divFloor(rl.getScreenHeight(), @as(i32, 2)) + 48, 50, rl.fade(rl.Color.black, alpha));
|
||||
rl.drawText(rl.textSubtext("raylib", 0, lettersCount), @divFloor(rl.getScreenWidth(), @as(i32, 2)) - 44, @divFloor(rl.getScreenHeight(), @as(i32, 2)) + 48, 50, .fade(.black, alpha));
|
||||
} else if (state == 4) {
|
||||
rl.drawText("[R] REPLAY", 340, 200, 20, rl.Color.gray);
|
||||
rl.drawText("[R] REPLAY", 340, 200, 20, .gray);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
192
examples/shapes/reasings.zig
Normal file
@ -0,0 +1,192 @@
|
||||
const math = @import("std").math;
|
||||
|
||||
// Linear Easing functions
|
||||
pub fn linearNone(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
return (c * t / d + b);
|
||||
}
|
||||
pub fn linearIn(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
return (c * t / d + b);
|
||||
}
|
||||
pub fn linearOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
return (c * t / d + b);
|
||||
}
|
||||
pub fn linearInOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
return (c * t / d + b);
|
||||
}
|
||||
|
||||
pub fn sineIn(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
return (-c * math.cos(t / d * (math.pi / 2.0)) + c + b);
|
||||
}
|
||||
pub fn sineOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
return (c * math.sin(t / d * (math.pi / 2.0)) + b);
|
||||
}
|
||||
pub fn sineInOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
return (-c / 2.0 * (math.cos(math.pi * t / d) - 1.0) + b);
|
||||
}
|
||||
|
||||
// Circular Easing functions
|
||||
pub fn circIn(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
const postFix = t / d;
|
||||
return (-c * (math.sqrt(1.0 - postFix * postFix) - 1.0) + b);
|
||||
}
|
||||
pub fn circOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
const postFix = t / d - 1.0;
|
||||
return (c * math.sqrt(1.0 - postFix * postFix) + b);
|
||||
}
|
||||
pub fn circInOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
var postFix = t / d;
|
||||
if ((postFix / 2.0) < 1.0) return (-c / 2.0 * (math.sqrt(1.0 - postFix * postFix) - 1.0) + b);
|
||||
postFix -= 2.0;
|
||||
return (c / 2.0 * (math.sqrt(1.0 - postFix * postFix) + 1.0) + b);
|
||||
}
|
||||
|
||||
// Cubic Easing functions
|
||||
pub fn cubicIn(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
const postFix = t / d;
|
||||
return (c * postFix * postFix * postFix + b);
|
||||
}
|
||||
pub fn cubicOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
const postFix = t / d - 1.0;
|
||||
return (c * (postFix * postFix * postFix + 1.0) + b);
|
||||
}
|
||||
pub fn cubicInOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
const postFix = t / d;
|
||||
if (postFix / 2.0 < 1.0) return (c / 2.0 * postFix * postFix * postFix + b);
|
||||
postFix -= 2.0;
|
||||
return (c / 2.0 * (t * t * t + 2.0) + b);
|
||||
}
|
||||
|
||||
// Quadratic Easing functions
|
||||
pub fn quadIn(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
const postfix = t / d;
|
||||
return (c * postfix * postfix + b);
|
||||
}
|
||||
pub fn quadOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
const postFix = t / d;
|
||||
return (-c * postFix * (postFix - 2.0) + b);
|
||||
}
|
||||
pub fn quadInOut(t: f32, b: f32, c: f32, d: f32) f32 // Ease: Quadratic In Out
|
||||
{
|
||||
const postFix = t / d;
|
||||
return if (postFix / 2 < 1)
|
||||
(((c / 2) * (postFix * postFix)) + b)
|
||||
else
|
||||
(-c / 2.0 * (((postFix - 1.0) * (postFix - 3.0)) - 1.0) + b);
|
||||
}
|
||||
|
||||
// Exponential Easing functions
|
||||
pub fn expoIn(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
return if (t == 0.0) b else (c * math.pow(f32, 2.0, 10.0 * (t / d - 1.0)) + b);
|
||||
}
|
||||
pub fn expoOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
return if (t == d) (b + c) else (c * (-math.pow(f32, 2.0, -10.0 * t / d) + 1.0) + b);
|
||||
}
|
||||
pub fn expoInOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
if (t == 0.0) return b;
|
||||
if (t == d) return (b + c);
|
||||
const postFix = t / d;
|
||||
if ((postFix / 2.0) < 1.0) return (c / 2.0 * math.pow(f32, 2.0, 10.0 * (postFix - 1.0)) + b);
|
||||
|
||||
return (c / 2.0 * (-math.pow(f32, 2.0, -10.0 * (postFix - 1.0)) + 2.0) + b);
|
||||
}
|
||||
|
||||
// Back Easing functions
|
||||
pub fn backIn(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
const s = 1.70158;
|
||||
const postFix = t / d;
|
||||
return (c * (postFix) * postFix * ((s + 1.0) * postFix - s) + b);
|
||||
}
|
||||
|
||||
pub fn backOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
const s = 1.70158;
|
||||
const postFix = t / d - 1.0;
|
||||
return (c * (postFix * postFix * ((s + 1.0) * postFix + s) + 1.0) + b);
|
||||
}
|
||||
|
||||
pub fn backInOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
const s = 1.70158;
|
||||
t /= d;
|
||||
if (t / 2.0 < 1.0) {
|
||||
s *= 1.525;
|
||||
return (c / 2.0 * (t * t * ((s + 1.0) * t - s)) + b);
|
||||
}
|
||||
t -= 2;
|
||||
const postFix = t;
|
||||
s *= 1.525;
|
||||
return (c / 2.0 * ((postFix) * t * ((s + 1.0) * t + s) + 2.0) + b);
|
||||
}
|
||||
|
||||
// Bounce Easing functions
|
||||
|
||||
pub fn bounceOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
var tDivD = t / d;
|
||||
if (tDivD < (1.0 / 2.75)) {
|
||||
return (c * (7.5625 * tDivD * tDivD) + b);
|
||||
} else if (tDivD < (2.0 / 2.75)) {
|
||||
tDivD -= (1.5 / 2.75);
|
||||
return (c * (7.5625 * tDivD * tDivD + 0.75) + b);
|
||||
} else if (tDivD < (2.5 / 2.75)) {
|
||||
tDivD -= (2.25 / 2.75);
|
||||
return (c * (7.5625 * tDivD * tDivD + 0.9375) + b);
|
||||
} else {
|
||||
tDivD -= (2.625 / 2.75);
|
||||
return (c * (7.5625 * tDivD * tDivD + 0.984375) + b);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bounceIn(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
return (c - bounceOut(d - t, 0.0, c, d) + b);
|
||||
}
|
||||
|
||||
pub fn bounceInOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
if (t < d / 2.0) return (bounceIn(t * 2.0, 0.0, c, d) * 0.5 + b);
|
||||
return (bounceOut(t * 2.0 - d, 0.0, c, d) * 0.5 + c * 0.5 + b);
|
||||
}
|
||||
|
||||
// Elastic Easing functions
|
||||
pub fn elasticIn(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
if (t == 0.0) return b;
|
||||
var tDivD = t / d;
|
||||
if (tDivD == 1.0) return (b + c);
|
||||
|
||||
const p = d * 0.3;
|
||||
const a = c;
|
||||
const s = p / 4.0;
|
||||
tDivD -= 1;
|
||||
const postFix = a * math.pow(f32, 2.0, 10.0 * tDivD);
|
||||
|
||||
return (-(postFix * math.sin((tDivD * d - s) * (2.0 * math.pi) / p)) + b);
|
||||
}
|
||||
|
||||
pub fn elasticOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
if (t == 0.0) return b;
|
||||
const tDivD = t / d;
|
||||
if (tDivD == 1.0) return (b + c);
|
||||
|
||||
const p = d * 0.3;
|
||||
const a = c;
|
||||
const s = p / 4.0;
|
||||
|
||||
return (a * math.pow(f32, 2.0, -10.0 * tDivD) * math.sin((tDivD * d - s) * (2.0 * math.pi) / p) + c + b);
|
||||
}
|
||||
|
||||
pub fn elasticInOut(t: f32, b: f32, c: f32, d: f32) f32 {
|
||||
if (t == 0.0) return b;
|
||||
const tDivD = t / d;
|
||||
if (tDivD / 2.0 == 2.0) return (b + c);
|
||||
|
||||
const p = d * (0.3 * 1.5);
|
||||
const a = c;
|
||||
const s = p / 4.0;
|
||||
|
||||
if (tDivD < 1.0) {
|
||||
tDivD -= 1;
|
||||
const postFix = a * math.pow(f32, 2.0, 10.0 * tDivD);
|
||||
return -0.5 * (postFix * math.sin((tDivD * d - s) * (2.0 * math.pi) / p)) + b;
|
||||
}
|
||||
|
||||
tDivD -= 1;
|
||||
const postFix = a * math.pow(f32, 2.0, -10.0 * (tDivD));
|
||||
|
||||
return (postFix * math.sin((tDivD * d - s) * (2.0 * math.pi) / p) * 0.5 + c + b);
|
||||
}
|
||||
@ -68,15 +68,15 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawText("Scale rectangle dragging from bottom-right corner!", 10, 10, 20, rl.Color.gray);
|
||||
rl.drawText("Scale rectangle dragging from bottom-right corner!", 10, 10, 20, .gray);
|
||||
|
||||
rl.drawRectangleRec(rec, rl.fade(rl.Color.green, 0.5));
|
||||
rl.drawRectangleRec(rec, .fade(.green, 0.5));
|
||||
|
||||
if (mouseScaleReady) {
|
||||
rl.drawRectangleLinesEx(rec, 1, rl.Color.red);
|
||||
rl.drawTriangle(rl.Vector2{ .x = rec.x + rec.width - mouseScaleMarkSize, .y = rec.y + rec.height }, rl.Vector2{ .x = rec.x + rec.width, .y = rec.y + rec.height }, rl.Vector2{ .x = rec.x + rec.width, .y = rec.y + rec.height - mouseScaleMarkSize }, rl.Color.red);
|
||||
rl.drawRectangleLinesEx(rec, 1, .red);
|
||||
rl.drawTriangle(rl.Vector2{ .x = rec.x + rec.width - mouseScaleMarkSize, .y = rec.y + rec.height }, rl.Vector2{ .x = rec.x + rec.width, .y = rec.y + rec.height }, rl.Vector2{ .x = rec.x + rec.width, .y = rec.y + rec.height - mouseScaleMarkSize }, .red);
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
226
examples/shapes/splines_drawing.zig
Normal file
@ -0,0 +1,226 @@
|
||||
const rl = @import("raylib");
|
||||
const rgui = @import("raygui");
|
||||
|
||||
const MAX_SPLINE_POINTS = 32;
|
||||
const screenWidth = 800;
|
||||
const screenHeight = 450;
|
||||
|
||||
// Cubic Bezier spline control points
|
||||
// NOTE: Every segment has two control points
|
||||
const ControlPoint = struct {
|
||||
start: rl.Vector2,
|
||||
end: rl.Vector2,
|
||||
};
|
||||
|
||||
// Spline types
|
||||
const SplineType = enum(i32) {
|
||||
linear = 0, // Linear
|
||||
basis = 1, // B-Spline
|
||||
catmullrom = 2, // Catmull-Rom
|
||||
bezier = 3, // Cubic Bezier
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
rl.setConfigFlags(.{ .msaa_4x_hint = true });
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib [shapes] example - splines drawing");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
var points: [MAX_SPLINE_POINTS]rl.Vector2 = undefined;
|
||||
points[0] = rl.Vector2{ .x = 50.0, .y = 400.0 };
|
||||
points[1] = rl.Vector2{ .x = 160.0, .y = 220.0 };
|
||||
points[2] = rl.Vector2{ .x = 340.0, .y = 380.0 };
|
||||
points[3] = rl.Vector2{ .x = 520.0, .y = 60.0 };
|
||||
points[4] = rl.Vector2{ .x = 710.0, .y = 260.0 };
|
||||
for (5..MAX_SPLINE_POINTS) |i| {
|
||||
points[i] = rl.Vector2{ .x = 0, .y = 0 };
|
||||
}
|
||||
|
||||
// Array required for spline bezier-cubic,
|
||||
// including control points interleaved with start-end segment points
|
||||
var pointsInterleaved: [3 * (MAX_SPLINE_POINTS - 1) + 1]rl.Vector2 = undefined;
|
||||
for (&pointsInterleaved) |*point| {
|
||||
point.* = rl.Vector2{ .x = 0, .y = 0 };
|
||||
}
|
||||
|
||||
var pointCount: usize = 5;
|
||||
var selectedPoint: ?*rl.Vector2 = null;
|
||||
var focusedPoint: ?*rl.Vector2 = null;
|
||||
var selectedControlPoint: ?*rl.Vector2 = null;
|
||||
var focusedControlPoint: ?*rl.Vector2 = null;
|
||||
|
||||
// Cubic Bezier control points initialization
|
||||
var control: [MAX_SPLINE_POINTS - 1]ControlPoint = undefined;
|
||||
for (&control) |*cp| {
|
||||
cp.* = .{ .end = .{ .x = 0, .y = 0 }, .start = .{ .x = 0, .y = 0 } };
|
||||
}
|
||||
for (0..pointCount) |i| {
|
||||
control[i].start = .{ .x = points[i].x + 50, .y = points[i].y };
|
||||
control[i].end = .{ .x = points[i + 1].x - 50, .y = points[i + 1].y };
|
||||
}
|
||||
|
||||
// Spline config variables
|
||||
var splineThickness: f32 = 8.0;
|
||||
var splineTypeActive = SplineType.linear;
|
||||
var splineTypeEditMode = false;
|
||||
var splineHelpersActive = true;
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Spline points creation logic (at the end of spline)
|
||||
if (rl.isMouseButtonPressed(.right) and (pointCount < MAX_SPLINE_POINTS)) {
|
||||
points[pointCount] = rl.getMousePosition();
|
||||
const i = pointCount - 1;
|
||||
control[i].start = rl.Vector2{ .x = points[i].x + 50, .y = points[i].y };
|
||||
control[i].end = rl.Vector2{ .x = points[i + 1].x - 50, .y = points[i + 1].y };
|
||||
pointCount += 1;
|
||||
}
|
||||
|
||||
// Spline point focus and selection logic
|
||||
if (selectedPoint == null and ((splineTypeActive != SplineType.bezier) or selectedControlPoint == null)) {
|
||||
focusedPoint = null;
|
||||
for (0..pointCount) |i| {
|
||||
if (rl.checkCollisionPointCircle(rl.getMousePosition(), points[i], 8.0)) {
|
||||
focusedPoint = &points[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rl.isMouseButtonPressed(.left)) selectedPoint = focusedPoint;
|
||||
}
|
||||
|
||||
// Spline point movement logic
|
||||
if (selectedPoint) |point| {
|
||||
point.* = rl.getMousePosition();
|
||||
if (rl.isMouseButtonReleased(.left)) selectedPoint = null;
|
||||
}
|
||||
|
||||
// Cubic Bezier spline control points logic
|
||||
if ((splineTypeActive == SplineType.bezier) and focusedPoint == null) {
|
||||
// Spline control point focus and selection logic
|
||||
if (selectedControlPoint == null) {
|
||||
focusedControlPoint = null;
|
||||
for (0..pointCount) |i| {
|
||||
if (rl.checkCollisionPointCircle(rl.getMousePosition(), control[i].start, 6.0)) {
|
||||
focusedControlPoint = &control[i].start;
|
||||
break;
|
||||
} else if (rl.checkCollisionPointCircle(rl.getMousePosition(), control[i].end, 6.0)) {
|
||||
focusedControlPoint = &control[i].end;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (rl.isMouseButtonPressed(.left)) selectedControlPoint = focusedControlPoint;
|
||||
}
|
||||
|
||||
// Spline control point movement logic
|
||||
if (selectedControlPoint) |cp| {
|
||||
cp.* = rl.getMousePosition();
|
||||
if (rl.isMouseButtonReleased(.left)) selectedControlPoint = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Spline selection logic
|
||||
splineTypeActive = switch (rl.getKeyPressed()) {
|
||||
.one => SplineType.linear,
|
||||
.two => SplineType.basis,
|
||||
.three => SplineType.catmullrom,
|
||||
.four => SplineType.basis,
|
||||
else => splineTypeActive,
|
||||
};
|
||||
|
||||
// Clear selection when changing to a spline without control points
|
||||
if (rl.isKeyPressed(.one) or rl.isKeyPressed(.two) or rl.isKeyPressed(.three)) selectedControlPoint = null;
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
switch (splineTypeActive) {
|
||||
SplineType.linear => rl.drawSplineLinear(points[0..pointCount], splineThickness, .red),
|
||||
SplineType.basis => rl.drawSplineBasis(points[0..pointCount], splineThickness, .red),
|
||||
SplineType.catmullrom => rl.drawSplineCatmullRom(points[0..pointCount], splineThickness, .red),
|
||||
SplineType.bezier => {
|
||||
// NOTE: Cubic-bezier spline requires the 2 control points of each segnment to be
|
||||
// provided interleaved with the start and end point of every segment
|
||||
for (0..pointCount - 1) |i| {
|
||||
pointsInterleaved[3 * i] = points[i];
|
||||
pointsInterleaved[3 * i + 1] = control[i].start;
|
||||
pointsInterleaved[3 * i + 2] = control[i].end;
|
||||
}
|
||||
|
||||
pointsInterleaved[3 * (pointCount - 1)] = points[pointCount - 1];
|
||||
|
||||
// Draw spline: cubic-bezier (with control points)
|
||||
rl.drawSplineBezierCubic(pointsInterleaved[0 .. 3 * pointCount], splineThickness, .red);
|
||||
|
||||
// Draw spline control points
|
||||
for (0..pointCount - 1) |i| {
|
||||
// Every cubic bezier point have two control points
|
||||
rl.drawCircleV(control[i].start, 6, .gold);
|
||||
rl.drawCircleV(control[i].end, 6, .gold);
|
||||
|
||||
if (focusedControlPoint == &control[i].start) rl.drawCircleV(control[i].start, 8, .green) else if (focusedControlPoint == &control[i].end) rl.drawCircleV(control[i].end, 8, .green);
|
||||
rl.drawLineEx(points[i], control[i].start, 1.0, .light_gray);
|
||||
rl.drawLineEx(points[i + 1], control[i].end, 1.0, .light_gray);
|
||||
|
||||
// Draw spline control lines
|
||||
rl.drawLineV(points[i], control[i].start, .gray);
|
||||
rl.drawLineV(control[i].end, points[i + 1], .gray);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
if (splineHelpersActive) {
|
||||
// Draw spline point helpers
|
||||
for (0..pointCount) |i| {
|
||||
const radius: f32 = if (focusedPoint == &points[i]) 12 else 8;
|
||||
const color: rl.Color = if (focusedPoint == &points[i]) .blue else .dark_blue;
|
||||
rl.drawCircleLinesV(points[i], radius, color);
|
||||
if ((splineTypeActive != SplineType.linear) and
|
||||
(splineTypeActive != SplineType.bezier) and
|
||||
(i < pointCount - 1)) rl.drawLineV(points[i], points[i + 1], .gray);
|
||||
|
||||
rl.drawText(rl.textFormat("[%.0f, %.0f]", .{ points[i].x, points[i].y }), @intFromFloat(points[i].x), @intFromFloat(points[i].y + 10), 10, .black);
|
||||
}
|
||||
}
|
||||
|
||||
// Check all possible UI states that require controls lock
|
||||
if (splineTypeEditMode or selectedPoint != null or selectedControlPoint != null) rgui.lock();
|
||||
|
||||
// Draw spline config
|
||||
_ = rgui.label(.{ .x = 12, .y = 62, .width = 140, .height = 24 }, rl.textFormat("Spline thickness: %i", .{@as(i64, @intFromFloat(splineThickness))}));
|
||||
|
||||
_ = rgui.sliderBar(.{ .x = 12, .y = 60 + 24, .width = 140, .height = 16 }, "", "", &splineThickness, 1.0, 40.0);
|
||||
|
||||
_ = rgui.checkBox(.{ .x = 12, .y = 110, .width = 20, .height = 20 }, "Show point helpers", &splineHelpersActive);
|
||||
|
||||
if (splineTypeEditMode) rgui.unlock();
|
||||
|
||||
_ = rgui.label(.{ .x = 12, .y = 10, .width = 140, .height = 24 }, "Spline type:");
|
||||
var active: i32 = @intFromEnum(splineTypeActive);
|
||||
if (rgui.dropdownBox(.{
|
||||
.x = 12,
|
||||
.y = 8 + 24,
|
||||
.width = 140,
|
||||
.height = 28,
|
||||
}, "LINEAR;BSPLINE;CATMULLROM;BEZIER", &active, splineTypeEditMode) > 0) splineTypeEditMode = !splineTypeEditMode;
|
||||
splineTypeActive = @enumFromInt(active);
|
||||
|
||||
rgui.unlock();
|
||||
}
|
||||
}
|
||||
341
examples/shapes/top_down_lights.zig
Normal file
@ -0,0 +1,341 @@
|
||||
const rl = @import("raylib");
|
||||
const std = @import("std");
|
||||
|
||||
// Custom Blend Modes
|
||||
const RLGL_SRC_ALPHA = 0x0302;
|
||||
const RLGL_MIN = 0x8007;
|
||||
const RLGL_MAX = 0x8008;
|
||||
|
||||
const MAX_BOXES = 20;
|
||||
/// MAX_BOXES *3. Each box can cast up to two shadow volumes for the edges it is away from, and one for the box itself
|
||||
const MAX_SHADOWS = MAX_BOXES * 3;
|
||||
const MAX_LIGHTS = 16;
|
||||
|
||||
// Shadow geometry type
|
||||
const ShadowGeometry = struct {
|
||||
vertices: [4]rl.Vector2,
|
||||
};
|
||||
|
||||
// Light info type
|
||||
const LightInfo = struct {
|
||||
/// Is this light slot active?
|
||||
active: bool,
|
||||
/// Does this light need to be updated?
|
||||
dirty: bool,
|
||||
/// Is this light in a valid position?
|
||||
valid: bool,
|
||||
|
||||
/// Light position
|
||||
position: rl.Vector2,
|
||||
/// Alpha mask for the light
|
||||
mask: rl.RenderTexture,
|
||||
/// The distance the light touches
|
||||
outerRadius: f32,
|
||||
/// A cached rectangle of the light bounds to help with culling
|
||||
bounds: rl.Rectangle,
|
||||
|
||||
shadows: [MAX_SHADOWS]ShadowGeometry,
|
||||
shadowCount: usize,
|
||||
};
|
||||
|
||||
var lights: [MAX_LIGHTS]LightInfo = undefined;
|
||||
|
||||
// Move a light and mark it as dirty so that we update it's mask next frame
|
||||
fn MoveLight(slot: usize, x: f32, y: f32) void {
|
||||
lights[slot].dirty = true;
|
||||
lights[slot].position.x = x;
|
||||
lights[slot].position.y = y;
|
||||
|
||||
// update the cached bounds
|
||||
lights[slot].bounds.x = x - lights[slot].outerRadius;
|
||||
lights[slot].bounds.y = y - lights[slot].outerRadius;
|
||||
}
|
||||
|
||||
// Compute a shadow volume for the edge
|
||||
// It takes the edge and projects it back by the light radius and turns it into a quad
|
||||
fn computeShadowVolumeForEdge(slot: usize, sp: rl.Vector2, ep: rl.Vector2) void {
|
||||
if (lights[slot].shadowCount >= MAX_SHADOWS) return;
|
||||
|
||||
const extension = lights[slot].outerRadius * 2;
|
||||
|
||||
const spVector = rl.math.vector2Normalize(rl.math.vector2Subtract(sp, lights[slot].position));
|
||||
const spProjection = rl.math.vector2Add(sp, rl.math.vector2Scale(spVector, extension));
|
||||
|
||||
const epVector = rl.math.vector2Normalize(rl.math.vector2Subtract(ep, lights[slot].position));
|
||||
const epProjection = rl.math.vector2Add(ep, rl.math.vector2Scale(epVector, extension));
|
||||
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[0] = sp;
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[1] = ep;
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[2] = epProjection;
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[3] = spProjection;
|
||||
|
||||
lights[slot].shadowCount += 1;
|
||||
}
|
||||
|
||||
// Draw the light and shadows to the mask for a light
|
||||
fn drawLightMask(slot: usize) void {
|
||||
// Use the light mask
|
||||
rl.beginTextureMode(lights[slot].mask);
|
||||
defer rl.endTextureMode();
|
||||
|
||||
rl.clearBackground(.white);
|
||||
|
||||
// Force the blend mode to only set the alpha of the destination
|
||||
rl.gl.rlSetBlendFactors(RLGL_SRC_ALPHA, RLGL_SRC_ALPHA, RLGL_MIN);
|
||||
rl.gl.rlSetBlendMode(@intFromEnum(rl.gl.rlBlendMode.rl_blend_custom));
|
||||
// defer going back to normal blend mode
|
||||
defer rl.gl.rlSetBlendMode(@intFromEnum(rl.gl.rlBlendMode.rl_blend_alpha));
|
||||
|
||||
// If we are valid, then draw the light radius to the alpha mask
|
||||
if (lights[slot].valid) rl.drawCircleGradient(@intFromFloat(lights[slot].position.x), @intFromFloat(lights[slot].position.y), lights[slot].outerRadius, rl.colorAlpha(.white, 0), .white);
|
||||
|
||||
rl.gl.rlDrawRenderBatchActive();
|
||||
|
||||
// Cut out the shadows from the light radius by forcing the alpha to maximum
|
||||
rl.gl.rlSetBlendMode(@intFromEnum(rl.gl.rlBlendMode.rl_blend_alpha));
|
||||
rl.gl.rlSetBlendFactors(RLGL_SRC_ALPHA, RLGL_SRC_ALPHA, RLGL_MAX);
|
||||
rl.gl.rlSetBlendMode(@intFromEnum(rl.gl.rlBlendMode.rl_blend_custom));
|
||||
|
||||
// Draw the shadows to the alpha mask
|
||||
for (0..lights[slot].shadowCount) |i| {
|
||||
rl.drawTriangleFan(&lights[slot].shadows[i].vertices, .white);
|
||||
}
|
||||
|
||||
rl.gl.rlDrawRenderBatchActive();
|
||||
}
|
||||
|
||||
// Setup a light
|
||||
fn setupLight(slot: usize, x: f32, y: f32, radius: f32) !void {
|
||||
lights[slot].active = true;
|
||||
lights[slot].valid = false; // The light must prove it is valid
|
||||
lights[slot].mask = try rl.loadRenderTexture(rl.getScreenWidth(), rl.getScreenHeight());
|
||||
lights[slot].outerRadius = radius;
|
||||
|
||||
lights[slot].bounds.width = radius * 2;
|
||||
lights[slot].bounds.height = radius * 2;
|
||||
|
||||
MoveLight(slot, x, y);
|
||||
|
||||
// Force the render texture to have something in it
|
||||
drawLightMask(slot);
|
||||
}
|
||||
|
||||
// See if a light needs to update it's mask
|
||||
// fn UpdateLight(slot: usize, Rectangle* boxes, int count) bool
|
||||
fn updateLight(slot: usize, boxes: []rl.Rectangle) bool {
|
||||
if (!lights[slot].active or !lights[slot].dirty) return false;
|
||||
|
||||
lights[slot].dirty = false;
|
||||
lights[slot].shadowCount = 0;
|
||||
lights[slot].valid = false;
|
||||
|
||||
for (boxes) |box| {
|
||||
// Are we in a box? if so we are not valid
|
||||
if (rl.checkCollisionPointRec(lights[slot].position, box)) return false;
|
||||
|
||||
// If this box is outside our bounds, we can skip it
|
||||
if (!rl.checkCollisionRecs(lights[slot].bounds, box)) continue;
|
||||
|
||||
// Check the edges that are on the same side we are, and cast shadow volumes out from them
|
||||
|
||||
// Top
|
||||
var sp = rl.Vector2{ .x = box.x, .y = box.y };
|
||||
var ep = rl.Vector2{ .x = box.x + box.width, .y = box.y };
|
||||
|
||||
if (lights[slot].position.y > ep.y) computeShadowVolumeForEdge(slot, sp, ep);
|
||||
|
||||
// Right
|
||||
sp = ep;
|
||||
ep.y += box.height;
|
||||
if (lights[slot].position.x < ep.x) computeShadowVolumeForEdge(slot, sp, ep);
|
||||
|
||||
// Bottom
|
||||
sp = ep;
|
||||
ep.x -= box.width;
|
||||
if (lights[slot].position.y < ep.y) computeShadowVolumeForEdge(slot, sp, ep);
|
||||
|
||||
// Left
|
||||
sp = ep;
|
||||
ep.y -= box.height;
|
||||
if (lights[slot].position.x > ep.x) computeShadowVolumeForEdge(slot, sp, ep);
|
||||
|
||||
// The box itself
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[0] = rl.Vector2{ .x = box.x, .y = box.y };
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[1] = rl.Vector2{ .x = box.x, .y = box.y + box.height };
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[2] = rl.Vector2{ .x = box.x + box.width, .y = box.y + box.height };
|
||||
lights[slot].shadows[lights[slot].shadowCount].vertices[3] = rl.Vector2{ .x = box.x + box.width, .y = box.y };
|
||||
lights[slot].shadowCount += 1;
|
||||
}
|
||||
|
||||
lights[slot].valid = true;
|
||||
|
||||
drawLightMask(slot);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Set up some boxes
|
||||
fn setupBoxes(boxes: []rl.Rectangle) void {
|
||||
boxes[0] = rl.Rectangle{ .x = 150, .y = 80, .width = 40, .height = 40 };
|
||||
boxes[1] = rl.Rectangle{ .x = 1200, .y = 700, .width = 40, .height = 40 };
|
||||
boxes[2] = rl.Rectangle{ .x = 200, .y = 600, .width = 40, .height = 40 };
|
||||
boxes[3] = rl.Rectangle{ .x = 1000, .y = 50, .width = 40, .height = 40 };
|
||||
boxes[4] = rl.Rectangle{ .x = 500, .y = 350, .width = 40, .height = 40 };
|
||||
|
||||
for (5..boxes.len) |i| {
|
||||
boxes[i] = rl.Rectangle{
|
||||
.x = @floatFromInt(rl.getRandomValue(0, rl.getScreenWidth())),
|
||||
.y = @floatFromInt(rl.getRandomValue(0, rl.getScreenHeight())),
|
||||
.width = @floatFromInt(rl.getRandomValue(10, 100)),
|
||||
.height = @floatFromInt(rl.getRandomValue(10, 100)),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screenWidth = 800;
|
||||
const screenHeight = 450;
|
||||
|
||||
rl.initWindow(screenWidth, screenHeight, "raylib [shapes] example - top down lights");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
// Initialize our 'world' of boxes
|
||||
var boxes: [MAX_BOXES]rl.Rectangle = undefined;
|
||||
setupBoxes(&boxes);
|
||||
|
||||
// Create a checkerboard ground texture
|
||||
const img = rl.genImageChecked(64, 64, 32, 32, .dark_brown, .dark_gray);
|
||||
defer rl.unloadImage(img);
|
||||
const backgroundTexture = try rl.loadTextureFromImage(img);
|
||||
defer rl.unloadTexture(backgroundTexture);
|
||||
|
||||
// Create a global light mask to hold all the blended lights
|
||||
const lightMask = try rl.loadRenderTexture(rl.getScreenWidth(), rl.getScreenHeight());
|
||||
defer rl.unloadRenderTexture(lightMask);
|
||||
|
||||
// Setup initial light
|
||||
try setupLight(0, 600, 400, 300);
|
||||
defer {
|
||||
//deinitialize light
|
||||
for (&lights) |*light| {
|
||||
if (light.active) rl.unloadRenderTexture(light.mask);
|
||||
}
|
||||
}
|
||||
var nextLight: usize = 1;
|
||||
|
||||
var showLines = false;
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Drag light 0
|
||||
if (rl.isMouseButtonDown(.left)) MoveLight(0, rl.getMousePosition().x, rl.getMousePosition().y);
|
||||
|
||||
// Make a new light
|
||||
if (rl.isMouseButtonPressed(.right) and (nextLight < MAX_LIGHTS)) {
|
||||
try setupLight(nextLight, rl.getMousePosition().x, rl.getMousePosition().y, 200);
|
||||
nextLight += 1;
|
||||
}
|
||||
|
||||
// Toggle debug info
|
||||
if (rl.isKeyPressed(.f1)) showLines = !showLines;
|
||||
|
||||
// Update the lights and keep track if any were dirty so we know if we need to update the master light mask
|
||||
var dirtyLights = false;
|
||||
for (0..MAX_LIGHTS) |i| {
|
||||
if (updateLight(i, &boxes)) dirtyLights = true;
|
||||
}
|
||||
|
||||
// Update the light mask
|
||||
if (dirtyLights) {
|
||||
// Build up the light mask
|
||||
rl.beginTextureMode(lightMask);
|
||||
defer rl.endTextureMode();
|
||||
|
||||
rl.clearBackground(.black);
|
||||
|
||||
// Force the blend mode to only set the alpha of the destination
|
||||
rl.gl.rlSetBlendFactors(RLGL_SRC_ALPHA, RLGL_SRC_ALPHA, RLGL_MIN);
|
||||
rl.gl.rlSetBlendMode(@intFromEnum(rl.gl.rlBlendMode.rl_blend_custom));
|
||||
defer rl.gl.rlSetBlendMode(@intFromEnum(rl.gl.rlBlendMode.rl_blend_alpha));
|
||||
|
||||
// Merge in all the light masks
|
||||
for (lights) |light| {
|
||||
if (light.active) rl.drawTextureRec(light.mask.texture, rl.Rectangle{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = @floatFromInt(rl.getScreenWidth()),
|
||||
.height = @floatFromInt(-rl.getScreenHeight()),
|
||||
}, rl.Vector2.zero(), .white);
|
||||
}
|
||||
|
||||
rl.gl.rlDrawRenderBatchActive();
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.black);
|
||||
|
||||
// Draw the tile background
|
||||
rl.drawTextureRec(backgroundTexture, rl.Rectangle{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = @floatFromInt(rl.getScreenWidth()),
|
||||
.height = @floatFromInt(rl.getScreenHeight()),
|
||||
}, rl.Vector2.zero(), .white);
|
||||
|
||||
// Overlay the shadows from all the lights
|
||||
rl.drawTextureRec(lightMask.texture, rl.Rectangle{
|
||||
.x = 0,
|
||||
.y = 0,
|
||||
.width = @floatFromInt(rl.getScreenWidth()),
|
||||
.height = @floatFromInt(-rl.getScreenHeight()),
|
||||
}, rl.Vector2.zero(), rl.colorAlpha(.white, if (showLines) 0.75 else 1.0));
|
||||
|
||||
// Draw the lights
|
||||
for (0..MAX_LIGHTS) |i| {
|
||||
if (lights[i].active) rl.drawCircle(@intFromFloat(lights[i].position.x), @intFromFloat(lights[i].position.y), 10, if (i == 0) .yellow else .white);
|
||||
}
|
||||
|
||||
if (showLines) {
|
||||
for (0..lights[0].shadowCount) |s| {
|
||||
rl.drawTriangleFan(&lights[0].shadows[s].vertices, .dark_purple);
|
||||
}
|
||||
|
||||
for (boxes) |box| {
|
||||
if (rl.checkCollisionRecs(box, lights[0].bounds)) rl.drawRectangleRec(box, .purple);
|
||||
|
||||
rl.drawRectangleLines(@intFromFloat(box.x), @intFromFloat(box.y), @intFromFloat(box.width), @intFromFloat(box.height), .dark_blue);
|
||||
}
|
||||
|
||||
rl.drawText("(F1) Hide Shadow Volumes", 10, 50, 10, .green);
|
||||
} else {
|
||||
rl.drawText("(F1) Show Shadow Volumes", 10, 50, 10, .green);
|
||||
}
|
||||
|
||||
rl.drawFPS(screenWidth - 80, 10);
|
||||
rl.drawText("Drag to move light #1", 10, 10, 10, .dark_green);
|
||||
rl.drawText("Right click to add new light", 10, 30, 10, .dark_green);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
// De-Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
166
examples/text/codepoints_loading.zig
Normal file
@ -0,0 +1,166 @@
|
||||
//!******************************************************************************************
|
||||
//!
|
||||
//! raylib-zog port of the [text] example - Codepoints loading
|
||||
//! https://github.com/raysan5/raylib/blob/master/examples/text/text_codepoints_loading.c
|
||||
//!
|
||||
//! Example complexity rating: [★★★☆] 3/4
|
||||
//!
|
||||
//! Example originally created with raylib 4.2, last time updated with raylib 2.5
|
||||
//!
|
||||
//! Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
//! BSD-like license that allows static linking with closed source software
|
||||
//!
|
||||
//! Translated to raylib-zig by Timothy Fiss (@TheFissk)
|
||||
//!
|
||||
//! Copyright (c) 2022-2025 Ramon Santamaria (@raysan5)
|
||||
//!
|
||||
//!*******************************************************************************************
|
||||
|
||||
const rl = @import("raylib");
|
||||
const std = @import("std");
|
||||
|
||||
/// Text to be displayed, must be UTF-8 (save this code file as UTF-8)
|
||||
/// NOTE: It can contain all the required text for the game,
|
||||
/// this text will be scanned to get all the required codepoints
|
||||
const text = "いろはにほへと ちりぬるを\nわかよたれそ つねならむ\nうゐのおくやま けふこえて\nあさきゆめみし ゑひもせす";
|
||||
|
||||
// Remove codepoint duplicates if requested
|
||||
// static int *CodepointRemoveDuplicates(int *codepoints, int codepointCount, int *codepointResultCount);
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.initWindow(screen_width, screen_height, "raylib [text] example - codepoints loading");
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
// Convert each utf-8 character into its
|
||||
// corresponding codepoint in the font file.
|
||||
const codepoints = try rl.loadCodepoints(text);
|
||||
const codepoints_count = codepoints.len;
|
||||
|
||||
//the DebugAllocator provides us with a nice general purpose allocator, great for small projects like this
|
||||
var font: rl.Font = undefined;
|
||||
var codepoints_no_dups: [:0]i32 = undefined;
|
||||
var codepoints_no_dups_count: usize = undefined;
|
||||
{
|
||||
var dba = std.heap.DebugAllocator(.{}){};
|
||||
var alloc = dba.allocator();
|
||||
// Removed duplicate codepoints to generate smaller font atlas
|
||||
codepoints_no_dups = try CodepointRemoveDuplicates(alloc, codepoints);
|
||||
codepoints_no_dups_count = std.mem.len(codepoints_no_dups.ptr);
|
||||
defer alloc.free(codepoints_no_dups);
|
||||
// we can free codepoints at the end of this block, atlas has already been generated
|
||||
rl.unloadCodepoints(codepoints);
|
||||
|
||||
// Load font containing all the provided codepoint glyphs
|
||||
// A texture font atlas is automatically generated
|
||||
// example assumes it is being run from the root of the project
|
||||
font = try rl.loadFontEx("examples/text/resources/DotGothic16-Regular.ttf", 36, codepoints_no_dups);
|
||||
|
||||
// Set bilinear scale filter for better font scaling
|
||||
rl.setTextureFilter(font.texture, .bilinear);
|
||||
rl.setTextLineSpacing(20); // Set line spacing for multiline text (when line breaks are included '\n')
|
||||
}
|
||||
defer rl.unloadFont(font); // Unload font at the end of the program
|
||||
|
||||
var show_font_atlas = false;
|
||||
|
||||
var codepoint_size: i32 = 0;
|
||||
var start: i32 = 0;
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (rl.isKeyPressed(.space)) show_font_atlas = !show_font_atlas;
|
||||
|
||||
// Testing code: getting next and previous codepoints on provided text
|
||||
if (rl.isKeyPressed(.right)) {
|
||||
// Get next codepoint in string and move pointer
|
||||
const err = rl.getCodepointNext(text[@intCast(start)..text.len], &codepoint_size);
|
||||
if (err == '?') @panic("getCodepointNext failed");
|
||||
if (start + codepoint_size < text.len) {
|
||||
start += codepoint_size;
|
||||
} else {
|
||||
start = text.len;
|
||||
}
|
||||
} else if (rl.isKeyPressed(.left)) {
|
||||
// Get previous codepoint in string and move pointer
|
||||
const err = rl.getCodepointPrevious(text[@intCast(start)..text.len], &codepoint_size);
|
||||
if (err == '?') @panic("getCodepointNext failed");
|
||||
if (start - codepoint_size > 0) {
|
||||
start -= codepoint_size;
|
||||
} else {
|
||||
start = 0;
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawRectangle(0, 0, rl.getScreenWidth(), 70, .black);
|
||||
rl.drawText(rl.textFormat("Total codepoints contained in provided text: %i", .{codepoints_count}), 10, 10, 20, .green);
|
||||
rl.drawText(rl.textFormat("Total codepoints required for font atlas (duplicates excluded): %u", .{codepoints_no_dups_count}), 10, 40, 20, .green);
|
||||
|
||||
if (show_font_atlas) {
|
||||
// Draw generated font texture atlas containing provided codepoints
|
||||
rl.drawTexture(font.texture, 150, 100, .black);
|
||||
rl.drawRectangleLines(150, 100, font.texture.width, font.texture.height, .black);
|
||||
} else {
|
||||
// Draw provided text with loaded font, containing all required codepoint glyphs
|
||||
rl.drawTextEx(font, text, .{ .x = 160, .y = 110 }, 48, 5, .black);
|
||||
}
|
||||
|
||||
rl.drawText("Press SPACE to toggle font atlas view!", 10, rl.getScreenHeight() - 30, 20, .gray);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
/// Remove codepoint duplicates if requested
|
||||
/// WARNING: This process could be a bit slow if there text to process is very long
|
||||
fn CodepointRemoveDuplicates(allocator: std.mem.Allocator, codepoints: []i32) ![:0]i32 {
|
||||
var no_dups: [:0]i32 = try allocator.allocSentinel(i32, codepoints.len, 0);
|
||||
std.mem.copyForwards(i32, no_dups, codepoints);
|
||||
|
||||
var no_dups_count: usize = no_dups.len;
|
||||
|
||||
// Remove duplicates
|
||||
var i: usize = 0;
|
||||
while (i < no_dups_count) {
|
||||
defer i += 1;
|
||||
var j: usize = i + 1;
|
||||
while (j < no_dups_count) {
|
||||
defer j += 1;
|
||||
const match = no_dups[i] == no_dups[j];
|
||||
if (match) {
|
||||
var k: usize = j;
|
||||
while (k < no_dups_count) {
|
||||
defer k += 1;
|
||||
no_dups[k] = no_dups[k + 1];
|
||||
}
|
||||
no_dups_count -= 1;
|
||||
j -= 1;
|
||||
no_dups[no_dups_count] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE: The size of codepointsNoDups is the same as original array but
|
||||
// only required positions are filled (codepointsNoDupsCount)
|
||||
return no_dups;
|
||||
}
|
||||
694
examples/text/draw_3d.zig
Normal file
@ -0,0 +1,694 @@
|
||||
//!******************************************************************************************
|
||||
//!
|
||||
//! raylib-zig port of the [text] example - Draw 3d
|
||||
//! https://github.com/raysan5/raylib/blob/master/examples/text/text_draw_3d.c
|
||||
//!
|
||||
//! Example complexity rating: [★★★★] 4/4
|
||||
//!
|
||||
//! NOTE: Draw a 2D text in 3D space, each letter is drawn in a quad (or 2 quads if backface is set)
|
||||
//! where the texture coodinates of each quad map to the texture coordinates of the glyphs
|
||||
//! inside the font texture.
|
||||
//!
|
||||
//! A more efficient approach, i believe, would be to render the text in a render texture and
|
||||
//! map that texture to a plane and render that, or maybe a shader but my method allows more
|
||||
//! flexibility...for example to change position of each letter individually to make somethink
|
||||
//! like a wavy text effect.
|
||||
//!
|
||||
//! Special thanks to:
|
||||
//! @Nighten for the DrawTextStyle() code https://github.com/NightenDushi/Raylib_DrawTextStyle
|
||||
//! Chris Camacho (codifies - http://bedroomcoders.co.uk/) for the alpha discard shader
|
||||
//!
|
||||
//! Example originally created with raylib 3.5, last time updated with raylib 4.0
|
||||
//!
|
||||
//! Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5)
|
||||
//! Translated to raylib-zig by Timothy Fiss (@TheFissk)
|
||||
//!
|
||||
//! 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) 2021-2025 Vlad Adrian (@demizdor)
|
||||
//!
|
||||
//!*******************************************************************************************
|
||||
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
const cl = @import("codepoints_loading.zig");
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Globals
|
||||
//--------------------------------------------------------------------------------------
|
||||
const letter_boundry_size = 0.25;
|
||||
const text_max_layers = 32;
|
||||
const letter_boundry_color = rl.Color.violet;
|
||||
|
||||
var show_letter_boundry = false;
|
||||
var show_text_boundry = false;
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Data Types definition
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Configuration structure for waving the text
|
||||
const WaveTextConfig = struct {
|
||||
waveRange: rl.Vector3,
|
||||
waveSpeed: rl.Vector3,
|
||||
waveOffset: rl.Vector3,
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.setConfigFlags(.{ .msaa_4x_hint = true, .vsync_hint = true });
|
||||
rl.initWindow(screen_width, screen_height, "raylib [text] example - draw 2D text in 3D");
|
||||
defer rl.closeWindow();
|
||||
|
||||
var spin = true; // Spin the camera?
|
||||
var multicolor = false; // Multicolor mode
|
||||
|
||||
// Define the camera to look into our 3d world
|
||||
var camera: rl.Camera3D = .{
|
||||
.position = .{ .x = -10, .y = 15, .z = -10 },
|
||||
.target = .{ .x = 0, .y = 0, .z = 0 },
|
||||
.up = .{ .x = 0, .y = 1, .z = 0 },
|
||||
.fovy = 45,
|
||||
.projection = .perspective,
|
||||
};
|
||||
var camera_mode = rl.CameraMode.orbital;
|
||||
|
||||
const cube_postition = rl.Vector3{ .x = 0.0, .y = 1.0, .z = 0.0 };
|
||||
const cube_size = rl.Vector3{ .x = 2.0, .y = 2.0, .z = 2.0 };
|
||||
|
||||
// Use the default font
|
||||
|
||||
const default_font = try rl.getFontDefault();
|
||||
defer rl.unloadFont(default_font);
|
||||
var font = try rl.getFontDefault();
|
||||
defer rl.unloadFont(font);
|
||||
var font_size: f32 = 0.8;
|
||||
var fontSpacing: f32 = 0.05;
|
||||
var lineSpacing: f32 = -0.1;
|
||||
|
||||
// var tbox = rl.Vector3{};
|
||||
var layers: usize = 1;
|
||||
var quads: usize = 0;
|
||||
var layerDistance: f32 = 0.01;
|
||||
|
||||
const wcfg = WaveTextConfig{
|
||||
.waveSpeed = .{ .x = 3, .y = 3, .z = 0.5 },
|
||||
.waveOffset = .{ .x = 0.35, .y = 0.35, .z = 0.35 },
|
||||
.waveRange = .{ .x = 0.45, .y = 0.45, .z = 0.45 },
|
||||
};
|
||||
|
||||
var time: f32 = 0.0;
|
||||
|
||||
// Setup a light and dark color
|
||||
var light = rl.Color.maroon;
|
||||
var dark = rl.Color.red;
|
||||
|
||||
// Load the alpha discard shader
|
||||
const alphaDiscard = try rl.loadShader(null, "examples/text/resources/shaders/glsl330/alpha_discard.fs");
|
||||
|
||||
// Array filled with multiple random colors (when multicolor mode is set)
|
||||
var multi: [text_max_layers]rl.Color = undefined;
|
||||
|
||||
// Set the text (using markdown!)
|
||||
var text = [_:0]u8{0} ** 64;
|
||||
var fw = std.Io.Writer.fixed(text[0..]);
|
||||
_ = try fw.writeAll("Hello ~~World~~ In 3D!");
|
||||
|
||||
rl.disableCursor(); // Limit cursor to relative movement inside the window
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.updateCamera(&camera, camera_mode);
|
||||
|
||||
// Handle font files dropped
|
||||
if (rl.isFileDropped()) {
|
||||
const droppedFiles: rl.FilePathList = rl.loadDroppedFiles();
|
||||
defer rl.unloadDroppedFiles(droppedFiles); // Unload filepaths from memory
|
||||
|
||||
// NOTE: We only support first ttf file dropped
|
||||
const path: [:0]const u8 = std.mem.span(droppedFiles.paths[0]);
|
||||
if (rl.isFileExtension(path, ".ttf")) {
|
||||
rl.unloadFont(font);
|
||||
font = try rl.loadFontEx(path, @intFromFloat(font_size), null);
|
||||
} else if (rl.isFileExtension(path, ".fnt")) {
|
||||
rl.unloadFont(font);
|
||||
font = try rl.loadFont(path);
|
||||
font_size = @floatFromInt(font.baseSize);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle Events
|
||||
if (rl.isKeyPressed(.f1)) show_letter_boundry = !show_letter_boundry;
|
||||
if (rl.isKeyPressed(.f2)) show_text_boundry = !show_text_boundry;
|
||||
if (rl.isKeyPressed(.f3)) {
|
||||
// Handle camera change
|
||||
spin = !spin;
|
||||
// we need to reset the camera when changing modes
|
||||
camera = rl.Camera3D{
|
||||
.target = .{ .x = 0.0, .y = 0.0, .z = 0.0 }, // Camera looking at point
|
||||
.up = .{ .x = 0.0, .y = 1.0, .z = 0.0 }, // Camera up vector (rotation towards target)
|
||||
.fovy = 45.0, // Camera field-of-view Y
|
||||
.projection = .perspective, // Camera mode type
|
||||
.position = .{ .x = 10.0, .y = 10.0, .z = -10.0 }, // Camera position
|
||||
};
|
||||
camera_mode = .free;
|
||||
|
||||
if (spin) {
|
||||
camera_mode = .orbital;
|
||||
camera.position = .{ .x = -10.0, .y = 15.0, .z = -10.0 }; // Camera position
|
||||
}
|
||||
}
|
||||
|
||||
// Handle clicking the cube
|
||||
if (rl.isMouseButtonPressed(.left)) {
|
||||
const ray = rl.getScreenToWorldRay(rl.getMousePosition(), camera);
|
||||
|
||||
// Check collision between ray and box
|
||||
const collision = rl.getRayCollisionBox(ray, .{ .max = .{ .x = cube_postition.x - cube_size.x / 2, .y = cube_postition.y - cube_size.y / 2, .z = cube_postition.z - cube_size.z / 2 }, .min = .{ .x = cube_postition.x + cube_size.x / 2, .y = cube_postition.y + cube_size.y / 2, .z = cube_postition.z + cube_size.z / 2 } });
|
||||
if (collision.hit) {
|
||||
// Generate new random colors
|
||||
light = generateRandomColor(0.5, 0.78);
|
||||
dark = generateRandomColor(0.4, 0.58);
|
||||
}
|
||||
}
|
||||
|
||||
// Handle text layers changes
|
||||
if (rl.isKeyPressed(.home)) {
|
||||
if (layers > 1) layers -= 1;
|
||||
} else if (rl.isKeyPressed(.end)) {
|
||||
if (layers < text_max_layers) layers += 1;
|
||||
}
|
||||
|
||||
// Handle text changes
|
||||
const key_pressed = rl.getKeyPressed();
|
||||
switch (key_pressed) {
|
||||
.left => font_size -= 0.5,
|
||||
.right => font_size += 0.5,
|
||||
.up => fontSpacing -= 0.1,
|
||||
.down => fontSpacing += 0.1,
|
||||
.page_up => lineSpacing -= 0.1,
|
||||
.page_down => lineSpacing += 0.1,
|
||||
.insert => layerDistance -= 0.001,
|
||||
.delete => layerDistance += 0.001,
|
||||
.tab => {
|
||||
multicolor = !multicolor; // Enable /disable multicolor mode
|
||||
|
||||
if (multicolor) {
|
||||
// Fill color array with random colors
|
||||
for (0..text_max_layers) |i| {
|
||||
multi[i] = generateRandomColor(0.5, 0.8);
|
||||
multi[i].a = @intCast(rl.getRandomValue(0, 255));
|
||||
}
|
||||
}
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
// Handle text input
|
||||
const ch = rl.getCharPressed();
|
||||
switch (key_pressed) {
|
||||
.backspace => {
|
||||
const len = rl.textLength(&text);
|
||||
if (len > 0) text[len - 1] = 0;
|
||||
},
|
||||
.enter => {
|
||||
const len = rl.textLength(&text);
|
||||
if (len < text.len - 1) {
|
||||
text[len] = '\n';
|
||||
text[len + 1] = 0;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
// append only printable chars
|
||||
const len = rl.textLength(&text);
|
||||
if (len < text.len) {
|
||||
text[len] = @intCast(ch);
|
||||
text[len + 1] = 0;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
// Measure 3D text so we can center it
|
||||
const tbox = measureTextWave3D(font, &text, font_size, fontSpacing, lineSpacing);
|
||||
|
||||
quads = 0; // Reset quad counter
|
||||
time += rl.getFrameTime(); // Update timer needed by `DrawTextWave3D()`
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
{
|
||||
rl.beginMode3D(camera);
|
||||
defer rl.endMode3D();
|
||||
rl.drawCubeV(cube_postition, cube_size, dark);
|
||||
rl.drawCubeWires(cube_postition, 2.1, 2.1, 2.1, light);
|
||||
|
||||
rl.drawGrid(10, 2.0);
|
||||
|
||||
// Use a shader to handle the depth buffer issue with transparent textures
|
||||
// NOTE: more info at https://bedroomcoders.co.uk/posts/198
|
||||
rl.beginShaderMode(alphaDiscard);
|
||||
defer rl.endShaderMode();
|
||||
|
||||
// Draw the 3D text above the red cube
|
||||
{
|
||||
rl.gl.rlPushMatrix();
|
||||
defer rl.gl.rlPopMatrix();
|
||||
rl.gl.rlRotatef(90.0, 1.0, 0.0, 0.0);
|
||||
rl.gl.rlRotatef(90.0, 0.0, 0.0, -1.0);
|
||||
|
||||
for (0..layers) |i| {
|
||||
var clr = light;
|
||||
if (multicolor) clr = multi[i];
|
||||
drawTextWave3D(font, &text, .{
|
||||
.x = -tbox.x / 2.0,
|
||||
.y = layerDistance * @as(f32, @floatFromInt(i)),
|
||||
.z = -4.5,
|
||||
}, font_size, fontSpacing, lineSpacing, true, wcfg, time, clr);
|
||||
}
|
||||
|
||||
// Draw the text boundry if set
|
||||
if (show_text_boundry) rl.drawCubeWiresV(.{ .x = 0.0, .y = 0.0, .z = -4.5 + tbox.z / 2 }, tbox, dark);
|
||||
}
|
||||
|
||||
// Don't draw the letter boundries for the 3D text below
|
||||
const slb = show_letter_boundry;
|
||||
show_letter_boundry = false;
|
||||
defer show_letter_boundry = slb;
|
||||
|
||||
// Draw 3D options (use default font)
|
||||
//-------------------------------------------------------------------------
|
||||
{
|
||||
rl.gl.rlPushMatrix();
|
||||
defer rl.gl.rlPopMatrix();
|
||||
rl.gl.rlRotatef(180.0, 0.0, 1.0, 0.0);
|
||||
|
||||
// In the C version of this library we use rl.textFormat to format our text. This doesn't play nice Zig's slice strings.
|
||||
// You might be able to make it work but I switched to using the std.fmt interfaces which are more ergonomic in zig anyways.
|
||||
// I use an oversized fixed buffer, but you could use an allocator to get a more robust solution
|
||||
|
||||
var text_buf = [_:0]u8{0} ** 64;
|
||||
|
||||
var opt = try std.fmt.bufPrintZ(&text_buf, "< SIZE: {d} >", .{font_size});
|
||||
var m = rl.measureTextEx(default_font, opt, 0.8, 0.1);
|
||||
var pos = rl.Vector3{ .x = -m.x / 2.0, .y = 0.01, .z = 2.0 };
|
||||
drawText3D(default_font, opt, pos, 0.8, 0.1, 0.0, false, .blue);
|
||||
pos.z += 0.5 + m.y;
|
||||
|
||||
opt = try std.fmt.bufPrintZ(&text_buf, "< SPACING: {d} >", .{fontSpacing});
|
||||
quads += std.mem.len(opt.ptr);
|
||||
m = rl.measureTextEx(default_font, opt, 0.8, 0.1);
|
||||
pos.x = -m.x / 2.0;
|
||||
drawText3D(default_font, opt, pos, 0.8, 0.1, 0.0, false, .blue);
|
||||
pos.z += 0.5 + m.y;
|
||||
|
||||
opt = try std.fmt.bufPrintZ(&text_buf, "< LINE: {d} >", .{lineSpacing});
|
||||
quads += std.mem.len(opt.ptr);
|
||||
m = rl.measureTextEx(default_font, opt, 0.8, 0.1);
|
||||
pos.x = -m.x / 2.0;
|
||||
drawText3D(default_font, opt, pos, 0.8, 0.1, 0.0, false, .blue);
|
||||
pos.z += 0.5 + m.y;
|
||||
|
||||
opt = try std.fmt.bufPrintZ(&text_buf, "< LBOX: {s} >", .{if (slb) "ON" else "OFF"});
|
||||
quads += std.mem.len(opt.ptr);
|
||||
m = rl.measureTextEx(default_font, opt, 0.8, 0.1);
|
||||
pos.x = -m.x / 2.0;
|
||||
drawText3D(default_font, opt, pos, 0.8, 0.1, 0.0, false, .red);
|
||||
pos.z += 0.5 + m.y;
|
||||
|
||||
opt = try std.fmt.bufPrintZ(&text_buf, "< TBOX: {s} >", .{if (show_text_boundry) "ON" else "OFF"});
|
||||
quads += std.mem.len(opt.ptr);
|
||||
m = rl.measureTextEx(default_font, opt, 0.8, 0.1);
|
||||
pos.x = -m.x / 2.0;
|
||||
drawText3D(default_font, opt, pos, 0.8, 0.1, 0.0, false, .red);
|
||||
pos.z += 0.5 + m.y;
|
||||
|
||||
opt = try std.fmt.bufPrintZ(&text_buf, "< LAYER DISTANCE: {d} >", .{layerDistance});
|
||||
quads += std.mem.len(opt.ptr);
|
||||
m = rl.measureTextEx(default_font, opt, 0.8, 0.1);
|
||||
pos.x = -m.x / 2.0;
|
||||
drawText3D(default_font, opt, pos, 0.8, 0.1, 0.0, false, .dark_purple);
|
||||
}
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// Draw 3D info text (use default font)
|
||||
//-------------------------------------------------------------------------
|
||||
const opt1 = "All the text displayed here is in 3D";
|
||||
quads += opt1.len;
|
||||
var m = rl.measureTextEx(default_font, opt1, 1.0, 0.05);
|
||||
var pos = rl.Vector3{ .x = -m.x / 2.0, .y = 0.01, .z = 2.0 };
|
||||
drawText3D(default_font, opt1, pos, 1.0, 0.05, 0.0, false, .dark_blue);
|
||||
pos.z += 1.5 + m.y;
|
||||
|
||||
const opt2 = "press [Left]/[Right] to change the font size";
|
||||
quads += opt2.len;
|
||||
m = rl.measureTextEx(default_font, opt2, 0.6, 0.05);
|
||||
pos.x = -m.x / 2.0;
|
||||
drawText3D(default_font, opt2, pos, 0.6, 0.05, 0.0, false, .dark_blue);
|
||||
pos.z += 0.5 + m.y;
|
||||
|
||||
const opt3 = "press [Up]/[Down] to change the font spacing";
|
||||
quads += opt3.len;
|
||||
m = rl.measureTextEx(default_font, opt3, 0.6, 0.05);
|
||||
pos.x = -m.x / 2.0;
|
||||
drawText3D(default_font, opt3, pos, 0.6, 0.05, 0.0, false, .dark_blue);
|
||||
pos.z += 0.5 + m.y;
|
||||
|
||||
const opt4 = "press [PgUp]/[PgDown] to change the line spacing";
|
||||
quads += opt4.len;
|
||||
m = rl.measureTextEx(default_font, opt4, 0.6, 0.05);
|
||||
pos.x = -m.x / 2.0;
|
||||
drawText3D(default_font, opt4, pos, 0.6, 0.05, 0.0, false, .dark_blue);
|
||||
pos.z += 0.5 + m.y;
|
||||
|
||||
const opt5 = "press [F1] to toggle the letter boundry";
|
||||
quads += opt5.len;
|
||||
m = rl.measureTextEx(default_font, opt5, 0.6, 0.05);
|
||||
pos.x = -m.x / 2.0;
|
||||
drawText3D(default_font, opt5, pos, 0.6, 0.05, 0.0, false, .dark_blue);
|
||||
pos.z += 0.5 + m.y;
|
||||
|
||||
const opt6 = "press [F2] to toggle the text boundry";
|
||||
quads += opt6.len;
|
||||
m = rl.measureTextEx(default_font, opt6, 0.6, 0.05);
|
||||
pos.x = -m.x / 2.0;
|
||||
drawText3D(default_font, opt6, pos, 0.6, 0.05, 0.0, false, .dark_blue);
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
// Draw 2D info text & stats
|
||||
//-------------------------------------------------------------------------
|
||||
rl.drawText("Drag & drop a font file to change the font!\nType something, see what happens!\n\nPress [F3] to toggle the camera", 10, 35, 10, .black);
|
||||
|
||||
quads += rl.textLength(&text) * 2 * layers;
|
||||
var buf = [_:0]u8{0} ** 70;
|
||||
const tmp = std.fmt.bufPrintZ(&buf, "{} layer(s) | {s} camera | {} quads ({} verts)", .{
|
||||
layers,
|
||||
if (spin) "ORBITAL" else "FREE",
|
||||
quads,
|
||||
quads * 4,
|
||||
}) catch unreachable;
|
||||
var width = rl.measureText(tmp, 10);
|
||||
rl.drawText(tmp, screen_width - 20 - width, 10, 10, .dark_green);
|
||||
|
||||
const tmp2 = "[Home]/[End] to add/remove 3D text layers";
|
||||
width = rl.measureText(tmp2, 10);
|
||||
rl.drawText(tmp2, screen_width - 20 - width, 25, 10, .dark_gray);
|
||||
|
||||
const tmp3 = "[Insert]/[Delete] to increase/decrease distance between layers";
|
||||
width = rl.measureText(tmp3, 10);
|
||||
rl.drawText(tmp3, screen_width - 20 - width, 40, 10, .dark_gray);
|
||||
|
||||
const tmp4 = "click the [CUBE] for a random color";
|
||||
width = rl.measureText(tmp4, 10);
|
||||
rl.drawText(tmp4, screen_width - 20 - width, 55, 10, .dark_gray);
|
||||
|
||||
const tmp5 = "[Tab] to toggle multicolor mode";
|
||||
width = rl.measureText(tmp5, 10);
|
||||
rl.drawText(tmp5, screen_width - 20 - width, 70, 10, .dark_gray);
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
rl.drawFPS(10, 10);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Module Functions Definitions
|
||||
//--------------------------------------------------------------------------------------
|
||||
/// Draw codepoint at specified position in 3D space
|
||||
fn drawTextCodepoint3D(font: rl.Font, codepoint: i32, start_position: rl.Vector3, fontSize: f32, backface: bool, tint: rl.Color) void {
|
||||
// Character index position in sprite font
|
||||
// NOTE: In case a codepoint is not available in the font, index returned points to '?'
|
||||
const index: usize = @intCast(rl.getGlyphIndex(font, codepoint));
|
||||
const scale: f32 = fontSize / @as(f32, @floatFromInt(font.baseSize));
|
||||
const glyphPadding: f32 = @floatFromInt(font.glyphPadding);
|
||||
|
||||
// Character destination rectangle on screen
|
||||
// NOTE: We consider charsPadding on drawing
|
||||
const position = rl.Vector3{
|
||||
.x = start_position.x + @as(f32, @floatFromInt(font.glyphs[index].offsetX - font.glyphPadding)) * scale,
|
||||
.y = start_position.y,
|
||||
.z = start_position.z + @as(f32, @floatFromInt(font.glyphs[index].offsetY - font.glyphPadding)) * scale,
|
||||
};
|
||||
|
||||
// Character source rectangle from font texture atlas
|
||||
// NOTE: We consider chars padding when drawing, it could be required for outline/glow shader effects
|
||||
const srcRec = rl.Rectangle{
|
||||
.x = font.recs[index].x - glyphPadding,
|
||||
.y = font.recs[index].y - glyphPadding,
|
||||
.width = font.recs[index].width + 2.0 * glyphPadding,
|
||||
.height = font.recs[index].height + 2.0 * glyphPadding,
|
||||
};
|
||||
|
||||
const width: f32 = (font.recs[index].width + 2.0 * glyphPadding) * scale;
|
||||
const height: f32 = (font.recs[index].height + 2.0 * glyphPadding) * scale;
|
||||
|
||||
if (font.texture.id > 0) {
|
||||
const x = 0.0;
|
||||
const y = 0.0;
|
||||
const z = 0.0;
|
||||
|
||||
// normalized texture coordinates of the glyph inside the font texture (0.0f -> 1.0f)
|
||||
const tx: f32 = srcRec.x / @as(f32, @floatFromInt(font.texture.width));
|
||||
const ty: f32 = srcRec.y / @as(f32, @floatFromInt(font.texture.height));
|
||||
const tw: f32 = (srcRec.x + srcRec.width) / @as(f32, @floatFromInt(font.texture.width));
|
||||
const th: f32 = (srcRec.y + srcRec.height) / @as(f32, @floatFromInt(font.texture.height));
|
||||
|
||||
if (show_letter_boundry) rl.drawCubeWiresV(.{ .x = position.x + width / 2, .y = position.y, .z = position.z + height / 2 }, .{ .x = width, .y = letter_boundry_size, .z = height }, letter_boundry_color);
|
||||
|
||||
//not entirely sure if this has a side effect, its in the original, so I'm not touching it
|
||||
_ = rl.gl.rlCheckRenderBatchLimit(if (backface) 8 else 4);
|
||||
rl.gl.rlSetTexture(font.texture.id);
|
||||
defer rl.gl.rlSetTexture(0);
|
||||
|
||||
rl.gl.rlPushMatrix();
|
||||
defer rl.gl.rlPopMatrix();
|
||||
rl.gl.rlTranslatef(position.x, position.y, position.z);
|
||||
|
||||
rl.gl.rlBegin(rl.gl.rl_quads);
|
||||
defer rl.gl.rlEnd();
|
||||
rl.gl.rlColor4ub(tint.r, tint.g, tint.b, tint.a);
|
||||
|
||||
// Front Face
|
||||
rl.gl.rlNormal3f(0.0, 1.0, 0.0); // Normal Pointing Up
|
||||
rl.gl.rlTexCoord2f(tx, ty);
|
||||
rl.gl.rlVertex3f(x, y, z); // Top Left Of The Texture and Quad
|
||||
rl.gl.rlTexCoord2f(tx, th);
|
||||
rl.gl.rlVertex3f(x, y, z + height); // Bottom Left Of The Texture and Quad
|
||||
rl.gl.rlTexCoord2f(tw, th);
|
||||
rl.gl.rlVertex3f(x + width, y, z + height); // Bottom Right Of The Texture and Quad
|
||||
rl.gl.rlTexCoord2f(tw, ty);
|
||||
rl.gl.rlVertex3f(x + width, y, z); // Top Right Of The Texture and Quad
|
||||
|
||||
if (backface) {
|
||||
// Back Face
|
||||
rl.gl.rlNormal3f(0.0, -1.0, 0.0); // Normal Pointing Down
|
||||
rl.gl.rlTexCoord2f(tx, ty);
|
||||
rl.gl.rlVertex3f(x, y, z); // Top Right Of The Texture and Quad
|
||||
rl.gl.rlTexCoord2f(tw, ty);
|
||||
rl.gl.rlVertex3f(x + width, y, z); // Top Left Of The Texture and Quad
|
||||
rl.gl.rlTexCoord2f(tw, th);
|
||||
rl.gl.rlVertex3f(x + width, y, z + height); // Bottom Left Of The Texture and Quad
|
||||
rl.gl.rlTexCoord2f(tx, th);
|
||||
rl.gl.rlVertex3f(x, y, z + height); // Bottom Right Of The Texture and Quad
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw a 2D text in 3D space
|
||||
fn drawText3D(font: rl.Font, text: [:0]const u8, position: rl.Vector3, font_size: f32, font_spacing: f32, line_spacing: f32, backface: bool, tint: rl.Color) void {
|
||||
const length = rl.textLength(text); // Total length in bytes of the text, scanned by codepoints in loop
|
||||
|
||||
var text_offset_y: f32 = 0.0; // Offset between lines (on line break '\n')
|
||||
var text_offset_x: f32 = 0.0; // Offset X to next character to draw
|
||||
|
||||
const scale = font_size / @as(f32, @floatFromInt(font.baseSize));
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < length) {
|
||||
// Get next codepoint from byte string and glyph index in font
|
||||
var codepoint_byte_count: i32 = 0;
|
||||
const codepoint = rl.getCodepoint(text[i..], &codepoint_byte_count);
|
||||
const index: usize = @intCast(rl.getGlyphIndex(font, codepoint));
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
|
||||
if (codepoint == 0x3f) codepoint_byte_count = 1;
|
||||
|
||||
if (codepoint == '\n') {
|
||||
// NOTE: Fixed line spacing of 1.5 line-height
|
||||
// TODO: Support custom line spacing defined by user
|
||||
text_offset_y += font_size + line_spacing;
|
||||
text_offset_x = 0.0;
|
||||
} else {
|
||||
if ((codepoint != ' ') and (codepoint != '\t')) {
|
||||
drawTextCodepoint3D(font, codepoint, .{
|
||||
.x = position.x + text_offset_x,
|
||||
.y = position.y,
|
||||
.z = position.z + text_offset_y,
|
||||
}, font_size, backface, tint);
|
||||
}
|
||||
|
||||
if (font.glyphs[index].advanceX == 0) {
|
||||
text_offset_x += font.recs[index].width * scale + font_spacing;
|
||||
} else {
|
||||
text_offset_x += @as(f32, @floatFromInt(font.glyphs[index].advanceX)) * scale + font_spacing;
|
||||
}
|
||||
}
|
||||
|
||||
i += @intCast(codepoint_byte_count); // Move text bytes counter to next codepoint
|
||||
}
|
||||
}
|
||||
|
||||
/// Draw a 2D text in 3D space and wave the parts that start with `~~` and end with `~~`.
|
||||
/// This is a modified version of the original code by @Nighten found here https://github.com/NightenDushi/Raylib_DrawTextStyle
|
||||
fn drawTextWave3D(font: rl.Font, text: [:0]const u8, position: rl.Vector3, fontSize: f32, fontSpacing: f32, lineSpacing: f32, backface: bool, config: WaveTextConfig, time: f32, tint: rl.Color) void {
|
||||
const length = rl.textLength(text); // Total length in bytes of the text, scanned by codepoints in loop
|
||||
|
||||
var text_offset_x: f32 = 0.0; // Offset X to next character to draw
|
||||
var text_offset_y: f32 = 0.0; // Offset between lines (on line break '\n')
|
||||
|
||||
const scale = fontSize / @as(f32, @floatFromInt(font.baseSize));
|
||||
|
||||
var wave = false;
|
||||
|
||||
var i: usize = 0;
|
||||
var k: usize = 0;
|
||||
while (i < length) : (k += 1) {
|
||||
|
||||
// Get next codepoint from byte string and glyph index in font
|
||||
var codepointByteCount: i32 = 0;
|
||||
const codepoint = rl.getCodepoint(text[i..], &codepointByteCount);
|
||||
const index: usize = @intCast(rl.getGlyphIndex(font, codepoint));
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
|
||||
if (codepoint == 0x3f) codepointByteCount = 1;
|
||||
|
||||
switch (codepoint) {
|
||||
'\n' => {
|
||||
// NOTE: Fixed line spacing of 1.5 line-height
|
||||
// TODO: Support custom line spacing defined by user
|
||||
text_offset_y += fontSize + lineSpacing;
|
||||
text_offset_x = 0.0;
|
||||
k = 0;
|
||||
},
|
||||
'~' => {
|
||||
if (rl.getCodepoint(text[i + 1 ..], &codepointByteCount) == '~') {
|
||||
codepointByteCount += 1;
|
||||
wave = !wave;
|
||||
}
|
||||
},
|
||||
else => {
|
||||
if ((codepoint != ' ') and (codepoint != '\t')) {
|
||||
var pos = position;
|
||||
if (wave) // Apply the wave effect
|
||||
{
|
||||
const kF: f32 = @floatFromInt(k);
|
||||
pos.x += std.math.sin(time * config.waveSpeed.x - kF * config.waveOffset.x) * config.waveRange.x;
|
||||
pos.y += std.math.sin(time * config.waveSpeed.y - kF * config.waveOffset.y) * config.waveRange.y;
|
||||
pos.z += std.math.sin(time * config.waveSpeed.z - kF * config.waveOffset.z) * config.waveRange.z;
|
||||
}
|
||||
|
||||
drawTextCodepoint3D(font, codepoint, .{
|
||||
.x = pos.x + text_offset_x,
|
||||
.y = pos.y,
|
||||
.z = pos.z + text_offset_y,
|
||||
}, fontSize, backface, tint);
|
||||
}
|
||||
|
||||
if (font.glyphs[index].advanceX == 0) {
|
||||
text_offset_x += font.recs[index].width * scale + fontSpacing;
|
||||
} else {
|
||||
text_offset_x += @as(f32, @floatFromInt(font.glyphs[index].advanceX)) * scale + fontSpacing;
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
i += @intCast(codepointByteCount); // Move text bytes counter to next codepoint
|
||||
}
|
||||
}
|
||||
|
||||
/// Measure a text in 3D ignoring the `~~` chars.
|
||||
fn measureTextWave3D(font: rl.Font, text: [:0]const u8, fontSize: f32, fontSpacing: f32, lineSpacing: f32) rl.Vector3 {
|
||||
const len = rl.textLength(text);
|
||||
var temp_len: usize = 0; // Used to count longer text line num chars
|
||||
var len_counter: usize = 0;
|
||||
|
||||
var temp_text_width: f32 = 0.0; // Used to count longer text line width
|
||||
|
||||
const scale = fontSize / @as(f32, @floatFromInt(font.baseSize));
|
||||
var text_height = scale;
|
||||
var text_width: f32 = 0.0;
|
||||
|
||||
var letter: i32 = 0; // Current character
|
||||
var index: usize = 0; // Index position in sprite font
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < len) {
|
||||
var next: i32 = 0;
|
||||
letter = rl.getCodepoint(text[i..], &next);
|
||||
index = @intCast(rl.getGlyphIndex(font, letter));
|
||||
|
||||
// NOTE: normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
// but we need to draw all of the bad bytes using the '?' symbol so to not skip any we set next = 1
|
||||
if (letter == 0x3f) next = 1;
|
||||
i += @intCast(next);
|
||||
|
||||
if (letter != '\n') {
|
||||
if (letter == '~' and rl.getCodepoint(text[i + 1 ..], &next) == '~') {
|
||||
i += 1;
|
||||
} else {
|
||||
len_counter += 1;
|
||||
if (font.glyphs[index].advanceX != 0) {
|
||||
text_width += @as(f32, @floatFromInt(font.glyphs[index].advanceX)) * scale;
|
||||
} else text_width += (font.recs[index].width + @as(f32, @floatFromInt(font.glyphs[index].offsetX))) * scale;
|
||||
}
|
||||
} else {
|
||||
if (temp_text_width < text_width) temp_text_width = text_width;
|
||||
len_counter = 0;
|
||||
text_width = 0.0;
|
||||
text_height += fontSize + lineSpacing;
|
||||
}
|
||||
|
||||
if (temp_len < len_counter) temp_len = len_counter;
|
||||
}
|
||||
|
||||
if (temp_text_width < text_width) temp_text_width = text_width;
|
||||
|
||||
const vec = rl.Vector3{
|
||||
.x = temp_text_width + (@as(f32, @floatFromInt(temp_len - 1)) * fontSpacing), // Adds chars spacing to measure
|
||||
.y = 0.25,
|
||||
.z = text_height,
|
||||
};
|
||||
|
||||
return vec;
|
||||
}
|
||||
|
||||
/// Generates a nice color with a random hue
|
||||
fn generateRandomColor(s: f32, v: f32) rl.Color {
|
||||
const Phi: f32 = 0.618033988749895; // Golden ratio conjugate
|
||||
var h: f32 = @floatFromInt(rl.getRandomValue(0, 360));
|
||||
h = std.math.mod(f32, (h + h * Phi), 360.0) catch 0;
|
||||
return rl.colorFromHSV(h, s, v);
|
||||
}
|
||||
143
examples/text/font_filters.zig
Normal file
@ -0,0 +1,143 @@
|
||||
//!*******************************************************************************************
|
||||
//!
|
||||
//! raylib-zig port of the [text] example - Font filters
|
||||
//! https://github.com/raysan5/raylib/blob/master/examples/text/text_font_filters.c
|
||||
//!
|
||||
//! Example complexity rating: [★★☆☆] 2/4
|
||||
//!
|
||||
//! NOTE: After font loading, font texture atlas filter could be configured for a softer
|
||||
//! display of the font when scaling it to different sizes, that way, it's not required
|
||||
//! to generate multiple fonts at multiple sizes (as long as the scaling is not very different)
|
||||
//!
|
||||
//! Example originally created with raylib 1.3, last time updated with raylib 4.2
|
||||
//!
|
||||
//! Translated to raylib-zig by Timothy Fiss (@TheFissk)
|
||||
//!
|
||||
//! 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) 2015-2025 Ramon Santamaria (@raysan5)
|
||||
//!
|
||||
//!*******************************************************************************************
|
||||
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.initWindow(screen_width, screen_height, "raylib [text] example - font filters");
|
||||
defer rl.closeWindow();
|
||||
|
||||
const msg = "Loaded Font";
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
// TTF Font loading with custom generation parameters
|
||||
var font = try rl.loadFontEx("examples/text/resources/KAISG.ttf", 96, null);
|
||||
|
||||
// Generate mipmap levels to use trilinear filtering
|
||||
// NOTE: On 2D drawing it won't be noticeable, it looks like FILTER_BILINEAR
|
||||
rl.genTextureMipmaps(&font.texture);
|
||||
|
||||
var font_size: f32 = @floatFromInt(font.baseSize);
|
||||
var fontPosition = rl.Vector2{ .x = 40.0, .y = screen_height / 2.0 - 80.0 };
|
||||
var text_size = rl.Vector2{ .x = 0.0, .y = 0.0 };
|
||||
|
||||
// Setup texture scaling filter
|
||||
rl.setTextureFilter(font.texture, .point);
|
||||
var currentFontFilter: i32 = 0; // TEXTURE_FILTER_POINT
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
font_size += rl.getMouseWheelMove() * 4.0;
|
||||
|
||||
// Choose font texture filter method
|
||||
const key_pressed = rl.getKeyPressed();
|
||||
switch (key_pressed) {
|
||||
.one => {
|
||||
rl.setTextureFilter(font.texture, .point);
|
||||
currentFontFilter = 0;
|
||||
},
|
||||
.two => {
|
||||
rl.setTextureFilter(font.texture, .bilinear);
|
||||
currentFontFilter = 1;
|
||||
},
|
||||
.three => {
|
||||
// NOTE: Trilinear filter won't be noticed on 2D drawing
|
||||
rl.setTextureFilter(font.texture, .trilinear);
|
||||
currentFontFilter = 2;
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
||||
text_size = rl.measureTextEx(font, msg, font_size, 0);
|
||||
|
||||
if (rl.isKeyDown(.left)) {
|
||||
fontPosition.x -= 10;
|
||||
} else if (rl.isKeyDown(.right)) {
|
||||
fontPosition.x += 10;
|
||||
}
|
||||
|
||||
// Load a dropped TTF file dynamically (at current fontSize)
|
||||
if (rl.isFileDropped()) {
|
||||
const dropped_files: rl.FilePathList = rl.loadDroppedFiles();
|
||||
defer rl.unloadDroppedFiles(dropped_files); // Unload filepaths from memory
|
||||
|
||||
// NOTE: We only support first ttf file dropped
|
||||
const path: [:0]const u8 = std.mem.span(dropped_files.paths[0]);
|
||||
if (rl.isFileExtension(path, ".ttf")) {
|
||||
rl.unloadFont(font);
|
||||
font = try rl.loadFontEx(path, @intFromFloat(font_size), null);
|
||||
} else if (rl.isFileExtension(path, ".fnt")) {
|
||||
rl.unloadFont(font);
|
||||
font = try rl.loadFont(path);
|
||||
font_size = @floatFromInt(font.baseSize);
|
||||
}
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawText("Use mouse wheel to change font size", 20, 20, 10, .gray);
|
||||
rl.drawText("Use KEY_RIGHT and KEY_LEFT to move text", 20, 40, 10, .gray);
|
||||
rl.drawText("Use 1, 2, 3 to change texture filter", 20, 60, 10, .gray);
|
||||
rl.drawText("Drop a new TTF font for dynamic loading", 20, 80, 10, .dark_gray);
|
||||
|
||||
rl.drawTextEx(font, msg, fontPosition, font_size, 0, .black);
|
||||
|
||||
// TODO: It seems texSize measurement is not accurate due to chars offsets...
|
||||
//DrawRectangleLines(fontPosition.x, fontPosition.y, textSize.x, textSize.y, RED);
|
||||
|
||||
rl.drawRectangle(0, screen_height - 80, screen_width, 80, .light_gray);
|
||||
rl.drawText(rl.textFormat("Font size: %02.02f", .{font_size}), 20, screen_height - 50, 10, .dark_gray);
|
||||
rl.drawText(rl.textFormat("Text size: [%02.02f, %02.02f]", .{ text_size.x, text_size.y }), 20, screen_height - 30, 10, .dark_gray);
|
||||
rl.drawText("CURRENT TEXTURE FILTER:", 250, 400, 20, .gray);
|
||||
|
||||
switch (currentFontFilter) {
|
||||
0 => rl.drawText("POINT", 570, 400, 20, .black),
|
||||
1 => rl.drawText("BILINEAR", 570, 400, 20, .black),
|
||||
2 => rl.drawText("TRILINEAR", 570, 400, 20, .black),
|
||||
else => unreachable,
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
95
examples/text/font_loading.zig
Normal file
@ -0,0 +1,95 @@
|
||||
//!******************************************************************************************
|
||||
//!
|
||||
//! raylib-zig port of the [text] example - Font loading
|
||||
//! https://github.com/raysan5/raylib/blob/master/examples/text/text_font_loading.c
|
||||
//!
|
||||
//! Example complexity rating: [★☆☆☆] 1/4
|
||||
//!
|
||||
//! NOTE: raylib can load fonts from multiple input file formats:
|
||||
//!
|
||||
//! - TTF/OTF > Sprite font atlas is generated on loading, user can configure
|
||||
//! some of the generation parameters (size, characters to include)
|
||||
//! - BMFonts > Angel code font fileformat, sprite font image must be provided
|
||||
//! together with the .fnt file, font generation cna not be configured
|
||||
//! - XNA Spritefont > Sprite font image, following XNA Spritefont conventions,
|
||||
//! Characters in image must follow some spacing and order rules
|
||||
//!
|
||||
//! Example originally created with raylib 1.4, last time updated with raylib 3.0
|
||||
//!
|
||||
//! Translated to raylib-zig by Timothy Fiss (@TheFissk)
|
||||
//!
|
||||
//! Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
//! BSD-like license that allows static linking with closed source software
|
||||
//!
|
||||
//! Copyright (c) 2016-2025 Ramon Santamaria (@raysan5)
|
||||
//!
|
||||
//!*******************************************************************************************
|
||||
|
||||
const rl = @import("raylib");
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.initWindow(screen_width, screen_height, "raylib [text] example - font loading");
|
||||
defer rl.closeWindow();
|
||||
|
||||
// Define characters to draw
|
||||
// NOTE: raylib supports UTF-8 encoding, following list is actually codified as UTF8 internally
|
||||
const msg = "!\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHI\nJKLMNOPQRSTUVWXYZ[]^_`abcdefghijklmn\nopqrstuvwxyz{|}~¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓ\nÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷\nøùúûüýþÿ";
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
// BMFont (AngelCode) : Font data and image atlas have been generated using external program
|
||||
const font_bm = try rl.loadFont("examples/text/resources/pixantiqua.fnt");
|
||||
defer rl.unloadFont(font_bm);
|
||||
|
||||
// TTF font : Font data and atlas are generated directly from TTF
|
||||
// NOTE: We define a font base size of 32 pixels tall and up-to 250 characters
|
||||
const font_ttf = try rl.loadFontEx("examples/text/resources/pixantiqua.ttf", 32, null);
|
||||
defer rl.unloadFont(font_ttf);
|
||||
|
||||
rl.setTextLineSpacing(16); // Set line spacing for multiline text (when line breaks are included '\n')
|
||||
|
||||
var use_ttf = false;
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (rl.isKeyDown(.space)) {
|
||||
use_ttf = true;
|
||||
} else {
|
||||
use_ttf = false;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawText("Hold SPACE to use TTF generated font", 20, 20, 20, .light_gray);
|
||||
|
||||
if (!use_ttf) {
|
||||
rl.drawTextEx(font_bm, msg, .{ .x = 20.0, .y = 100.0 }, @floatFromInt(font_bm.baseSize), 2, .maroon);
|
||||
rl.drawText("Using BMFont (Angelcode) imported", 20, rl.getScreenHeight() - 30, 20, .gray);
|
||||
} else {
|
||||
rl.drawTextEx(font_ttf, msg, .{ .x = 20.0, .y = 100.0 }, @floatFromInt(font_ttf.baseSize), 2, .lime);
|
||||
rl.drawText("Using TTF font generated", 20, rl.getScreenHeight() - 30, 20, .gray);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
132
examples/text/font_sdf.zig
Normal file
@ -0,0 +1,132 @@
|
||||
//!*******************************************************************************************
|
||||
//!
|
||||
//! raylib-zig port of the [text] example - Font SDF loading
|
||||
//! https://github.com/raysan5/raylib/blob/master/examples/text/text_font_sdf.c
|
||||
//!
|
||||
//! Example complexity rating: [★★★☆] 3/4
|
||||
//!
|
||||
//! Example originally created with raylib 1.3, last time updated with raylib 4.0
|
||||
//!
|
||||
//! Translated to raylib-zig by Timothy Fiss (@TheFissk)
|
||||
//!
|
||||
//! 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) 2015-2025 Ramon Santamaria (@raysan5)
|
||||
//!
|
||||
//!*******************************************************************************************
|
||||
|
||||
const std = @import("std");
|
||||
const rl = @import("raylib");
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.initWindow(screen_width, screen_height, "raylib [text] example - SDF fonts");
|
||||
defer rl.closeWindow();
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
|
||||
const msg = "Signed Distance Fields";
|
||||
|
||||
// Loading file to memory
|
||||
const font_default = try rl.loadFontEx("examples/text/resources/anonymous_pro_bold.ttf", 16, null);
|
||||
defer font_default.unload();
|
||||
var font_sdf: rl.Font = font_default;
|
||||
defer font_sdf.unload();
|
||||
{
|
||||
// SDF font generation from TTF font
|
||||
const file_data = try rl.loadFileData("examples/text/resources/anonymous_pro_bold.ttf");
|
||||
defer rl.unloadFileData(file_data); // Free memory from loaded file
|
||||
|
||||
font_sdf = .{
|
||||
.baseSize = 16,
|
||||
.glyphCount = 95,
|
||||
.glyphPadding = 0,
|
||||
.glyphs = @ptrCast(try rl.loadFontData(@ptrCast(file_data), 16, null, .sdf)),
|
||||
.texture = undefined,
|
||||
.recs = undefined,
|
||||
};
|
||||
const atlas_image, const atlas_recs = try rl.genImageFontAtlas(font_sdf.glyphs[0..@intCast(font_sdf.glyphCount)], font_sdf.baseSize, 0, 1);
|
||||
defer atlas_image.unload();
|
||||
font_sdf.texture = try rl.loadTextureFromImage(atlas_image);
|
||||
font_sdf.recs = @ptrCast(atlas_recs);
|
||||
}
|
||||
|
||||
// Load SDF required shader (we use default vertex shader)
|
||||
const shader = try rl.loadShader(null, "examples/text/resources/shaders/glsl330/sdf.fs");
|
||||
defer rl.unloadShader(shader);
|
||||
rl.setTextureFilter(font_sdf.texture, .bilinear); // Required for SDF font
|
||||
|
||||
var font_position = rl.Vector2{ .x = 40, .y = @as(f32, @floatFromInt(screen_height)) / 2.0 - 50 };
|
||||
var text_size = rl.Vector2{ .x = 0.0, .y = 0.0 };
|
||||
var font_size: f32 = 16.0;
|
||||
var current_font: i32 = 0; // 0 - fontDefault, 1 - fontSDF
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
font_size += rl.getMouseWheelMove() * 8.0;
|
||||
|
||||
if (font_size < 6) font_size = 6;
|
||||
|
||||
if (rl.isKeyDown(.space)) {
|
||||
current_font = 1;
|
||||
} else {
|
||||
current_font = 0;
|
||||
}
|
||||
|
||||
if (current_font == 0) {
|
||||
text_size = rl.measureTextEx(font_default, msg, font_size, 0);
|
||||
} else {
|
||||
text_size = rl.measureTextEx(font_sdf, msg, font_size, 0);
|
||||
}
|
||||
|
||||
font_position.x = @as(f32, @floatFromInt(rl.getScreenWidth())) / 2 - text_size.x / 2;
|
||||
font_position.y = @as(f32, @floatFromInt(rl.getScreenHeight())) / 2 - text_size.y / 2 + 80;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
if (current_font == 1) {
|
||||
// NOTE: SDF fonts require a custom SDf shader to compute fragment color
|
||||
rl.beginShaderMode(shader); // Activate SDF font shader
|
||||
rl.drawTextEx(font_sdf, msg, font_position, font_size, 0, .black);
|
||||
rl.endShaderMode(); // Activate our default shader for next drawings
|
||||
|
||||
rl.drawTexture(font_sdf.texture, 10, 10, .black);
|
||||
} else {
|
||||
rl.drawTextEx(font_default, msg, font_position, font_size, 0, .black);
|
||||
rl.drawTexture(font_default.texture, 10, 10, .black);
|
||||
}
|
||||
|
||||
if (current_font == 1) {
|
||||
rl.drawText("SDF!", 320, 20, 80, .red);
|
||||
} else {
|
||||
rl.drawText("default font", 315, 40, 30, .gray);
|
||||
}
|
||||
|
||||
rl.drawText("FONT SIZE: 16.0", rl.getScreenWidth() - 240, 20, 20, .dark_gray);
|
||||
rl.drawText(rl.textFormat("RENDER SIZE: %02.02f", .{font_size}), rl.getScreenWidth() - 240, 50, 20, .dark_gray);
|
||||
rl.drawText("Use MOUSE WHEEL to SCALE TEXT!", rl.getScreenWidth() - 240, 90, 10, .dark_gray);
|
||||
rl.drawText("HOLD SPACE to USE SDF FONT VERSION!", 340, rl.getScreenHeight() - 30, 20, .maroon);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
94
examples/text/font_spritefont.zig
Normal file
@ -0,0 +1,94 @@
|
||||
//!******************************************************************************************
|
||||
//!
|
||||
//! raylib-zig port of the [text] example - Sprite font loading
|
||||
//! https://github.com/raysan5/raylib/blob/master/examples/text/text_font_spritefont.c
|
||||
//!
|
||||
//! Example complexity rating: [★☆☆☆] 1/4
|
||||
//!
|
||||
//! NOTE: Sprite fonts should be generated following this conventions:
|
||||
//!
|
||||
//! - Characters must be ordered starting with character 32 (Space)
|
||||
//! - Every character must be contained within the same Rectangle height
|
||||
//! - Every character and every line must be separated by the same distance (margin/padding)
|
||||
//! - Rectangles must be defined by a MAGENTA color background
|
||||
//!
|
||||
//! Following those constraints, a font can be provided just by an image,
|
||||
//! this is quite handy to avoid additional font descriptor files (like BMFonts use).
|
||||
//!
|
||||
//! Example originally created with raylib 1.0, last time updated with raylib 1.0
|
||||
//!
|
||||
//! Translated to raylib-zig by Timothy Fiss (@TheFissk)
|
||||
//!
|
||||
//! Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
//! BSD-like license that allows static linking with closed source software
|
||||
//!
|
||||
//! Copyright (c) 2014-2025 Ramon Santamaria (@raysan5)
|
||||
//!
|
||||
//!*******************************************************************************************
|
||||
|
||||
const rl = @import("raylib");
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.initWindow(screen_width, screen_height, "raylib [text] example - sprite font loading");
|
||||
defer rl.closeWindow();
|
||||
|
||||
const msg1 = "THIS IS A custom SPRITE FONT...";
|
||||
const msg2 = "...and this is ANOTHER CUSTOM font...";
|
||||
const msg3 = "...and a THIRD one! GREAT! :D";
|
||||
|
||||
// NOTE: Textures/Fonts MUST be loaded after Window initialization (OpenGL context is required)
|
||||
const font1 = try rl.loadFont("examples/text/resources/custom_mecha.png"); // Font loading
|
||||
defer rl.unloadFont(font1);
|
||||
const font2 = try rl.loadFont("examples/text/resources/custom_alagard.png"); // Font loading
|
||||
defer rl.unloadFont(font2);
|
||||
const font3 = try rl.loadFont("examples/text/resources/custom_jupiter_crash.png"); // Font loading
|
||||
defer rl.unloadFont(font3);
|
||||
|
||||
const font_position1 = rl.Vector2{
|
||||
.x = @as(f32, @floatFromInt(screen_width)) / 2.0 - rl.measureTextEx(font1, msg1, @floatFromInt(font1.baseSize), -3).x / 2,
|
||||
.y = @as(f32, @floatFromInt(screen_height)) / 2.0 - @as(f32, @floatFromInt(font1.baseSize)) / 2.0 - 80.0,
|
||||
};
|
||||
|
||||
const font_position2 = rl.Vector2{
|
||||
.x = @as(f32, @floatFromInt(screen_width)) / 2.0 - rl.measureTextEx(font2, msg2, @floatFromInt(font2.baseSize), -2).x / 2,
|
||||
.y = @as(f32, @floatFromInt(screen_height)) / 2.0 - @as(f32, @floatFromInt(font1.baseSize)) / 2.0 - 10.0,
|
||||
};
|
||||
|
||||
const font_position3 = rl.Vector2{
|
||||
.x = @as(f32, @floatFromInt(screen_width)) / 2.0 - rl.measureTextEx(font3, msg3, @floatFromInt(font3.baseSize), 2).x / 2,
|
||||
.y = @as(f32, @floatFromInt(screen_height)) / 2.0 - @as(f32, @floatFromInt(font1.baseSize)) / 2.0 + 50.0,
|
||||
};
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// TODO: Update variables here...
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawTextEx(font1, msg1, font_position1, @floatFromInt(font1.baseSize), -3, .white);
|
||||
rl.drawTextEx(font2, msg2, font_position2, @floatFromInt(font2.baseSize), -2, .white);
|
||||
rl.drawTextEx(font3, msg3, font_position3, @floatFromInt(font3.baseSize), 2, .white);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
@ -35,15 +35,15 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.white);
|
||||
rl.clearBackground(.white);
|
||||
|
||||
rl.drawText(rl.textFormat("Score: %08i", .{score}), 200, 80, 20, rl.Color.red);
|
||||
rl.drawText(rl.textFormat("Score: %08i", .{score}), 200, 80, 20, .red);
|
||||
|
||||
rl.drawText(rl.textFormat("HiScore: %08i", .{hiscore}), 200, 120, 20, rl.Color.green);
|
||||
rl.drawText(rl.textFormat("HiScore: %08i", .{hiscore}), 200, 120, 20, .green);
|
||||
|
||||
rl.drawText(rl.textFormat("Lives: %02i", .{lives}), 200, 160, 40, rl.Color.blue);
|
||||
rl.drawText(rl.textFormat("Lives: %02i", .{lives}), 200, 160, 40, .blue);
|
||||
|
||||
rl.drawText(rl.textFormat("Elapsed Time: %02.02f ms", .{rl.getFrameTime() * 1000}), 200, 220, 20, rl.Color.black);
|
||||
rl.drawText(rl.textFormat("Elapsed Time: %02.02f ms", .{rl.getFrameTime() * 1000}), 200, 220, 20, .black);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
126
examples/text/input_box.zig
Normal file
@ -0,0 +1,126 @@
|
||||
//!******************************************************************************************
|
||||
//!
|
||||
//! raylib-zig port of the [raylib-zig port of the [text] example - Input Box
|
||||
//! https://github.com/raysan5/raylib/blob/master/examples/text/text_input_box.c
|
||||
//!
|
||||
//! Example complexity rating: [★★☆☆] 2/4
|
||||
//!
|
||||
//! Example originally created with raylib 1.7, last time updated with raylib 3.5
|
||||
//!
|
||||
//! Translated to raylib-zig by Timothy Fiss (@TheFissk)
|
||||
//!
|
||||
//! 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) 2017-2025 Ramon Santamaria (@raysan5)
|
||||
//!
|
||||
//!*******************************************************************************************
|
||||
|
||||
const rl = @import("raylib");
|
||||
|
||||
const max_input_chars = 9;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.initWindow(screen_width, screen_height, "raylib [text] example - input box");
|
||||
defer rl.closeWindow();
|
||||
|
||||
var name = [_:0]u8{0} ** max_input_chars;
|
||||
var letter_count: usize = 0;
|
||||
|
||||
const text_box = rl.Rectangle{
|
||||
.x = @as(f32, @floatFromInt(screen_width)) / 2.0 - 100,
|
||||
.y = 180,
|
||||
.width = 255,
|
||||
.height = 50,
|
||||
};
|
||||
var mouse_on_text = false;
|
||||
|
||||
var framesCounter: usize = 0;
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
mouse_on_text = rl.checkCollisionPointRec(rl.getMousePosition(), text_box);
|
||||
|
||||
if (mouse_on_text) {
|
||||
// Set the window's cursor to the I-Beam
|
||||
rl.setMouseCursor(.ibeam);
|
||||
|
||||
// Get char pressed (unicode character) on the queue
|
||||
// Check if more characters have been pressed on the same frame
|
||||
var key = rl.getKeyPressed();
|
||||
while (key != .null) : (key = rl.getKeyPressed()) {
|
||||
// NOTE: Only allow keys in range [32..125]
|
||||
const keyInt: c_int = @intFromEnum(key);
|
||||
if ((keyInt >= 32) and (keyInt <= 125) and (letter_count < name.len)) {
|
||||
name[letter_count] = @intCast(keyInt);
|
||||
letter_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (rl.isKeyPressed(.backspace)) {
|
||||
if (letter_count <= 1) {
|
||||
letter_count = 0;
|
||||
} else {
|
||||
letter_count -= 1;
|
||||
}
|
||||
name[letter_count] = 0;
|
||||
}
|
||||
} else rl.setMouseCursor(.default);
|
||||
|
||||
if (mouse_on_text) {
|
||||
framesCounter += 1;
|
||||
} else {
|
||||
framesCounter = 0;
|
||||
}
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawText("PLACE MOUSE OVER INPUT BOX!", 240, 140, 20, .gray);
|
||||
|
||||
rl.drawRectangleRec(text_box, .light_gray);
|
||||
rl.drawRectangleLines(
|
||||
@intFromFloat(text_box.x),
|
||||
@intFromFloat(text_box.y),
|
||||
@intFromFloat(text_box.width),
|
||||
@intFromFloat(text_box.height),
|
||||
if (mouse_on_text) .red else .dark_gray,
|
||||
);
|
||||
|
||||
rl.drawText(&name, @intFromFloat(text_box.x + 5), @intFromFloat(text_box.y + 8), 40, .maroon);
|
||||
|
||||
rl.drawText(rl.textFormat("INPUT CHARS: %i/%i", .{ letter_count, @as(usize, @intCast(max_input_chars)) }), 315, 250, 20, .dark_gray);
|
||||
|
||||
if (mouse_on_text) {
|
||||
if (letter_count < max_input_chars) {
|
||||
// Draw blinking underscore char
|
||||
if (((framesCounter / 20) % 2) == 0) {
|
||||
rl.drawText("_", @as(i32, @intFromFloat(text_box.x)) + 8 + rl.measureText(&name, 40), @intFromFloat(text_box.y + 12), 40, .maroon);
|
||||
}
|
||||
} else {
|
||||
rl.drawText("Press BACKSPACE to delete chars...", 230, 300, 20, .gray);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
282
examples/text/rectangle_bounds.zig
Normal file
@ -0,0 +1,282 @@
|
||||
//!******************************************************************************************
|
||||
//!
|
||||
//! raylib-zig port of the [text] example - Rectangle bounds
|
||||
//!
|
||||
//! Example complexity rating: [★★★★] 4/4
|
||||
//!
|
||||
//! Example originally created with raylib 2.5, last time updated with raylib 4.0
|
||||
//!
|
||||
//! Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5)
|
||||
//!
|
||||
//! Translated to raylib-zig by Timothy Fiss (@TheFissk)
|
||||
//!
|
||||
//! Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
//! BSD-like license that allows static linking with closed source software
|
||||
//!
|
||||
//! Copyright (c) 2018-2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
//!
|
||||
//!*******************************************************************************************
|
||||
|
||||
const rl = @import("raylib");
|
||||
const std = @import("std");
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.initWindow(screen_width, screen_height, "raylib [text] example - draw text inside a rectangle");
|
||||
defer rl.closeWindow();
|
||||
|
||||
const text: [:0]const u8 = "Text cannot escape\tthis container\t...word wrap also works when active so here's a long text for testing.\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Nec ullamcorper sit amet risus nullam eget felis eget.";
|
||||
|
||||
var resizing = false;
|
||||
var word_wrap = true;
|
||||
|
||||
var container = rl.Rectangle{
|
||||
.x = 25.0,
|
||||
.y = 25.0,
|
||||
.width = @floatFromInt(screen_width - 50),
|
||||
.height = @floatFromInt(screen_height - 250),
|
||||
};
|
||||
var resizer = rl.Rectangle{
|
||||
.x = container.x + container.width - 17,
|
||||
.y = container.y + container.height - 17,
|
||||
.width = 14,
|
||||
.height = 14,
|
||||
};
|
||||
|
||||
// Minimum width and heigh for the container rectangle
|
||||
const minWidth = 60.0;
|
||||
const minHeight = 60.0;
|
||||
const maxWidth = screen_width - 50.0;
|
||||
const maxHeight = screen_height - 160.0;
|
||||
|
||||
var lastMouse = rl.Vector2{ .x = 0.0, .y = 0.0 }; // Stores last mouse coordinates
|
||||
var border_color = rl.Color.maroon; // Container border color
|
||||
const font = try rl.getFontDefault(); // Get default system font
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main game loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
if (rl.isKeyPressed(.space)) word_wrap = !word_wrap;
|
||||
|
||||
const mouse = rl.getMousePosition();
|
||||
|
||||
// Check if the mouse is inside the container and toggle border color
|
||||
if (rl.checkCollisionPointRec(mouse, container)) {
|
||||
border_color = rl.fade(.maroon, 0.4);
|
||||
} else if (!resizing) {
|
||||
border_color = .maroon;
|
||||
}
|
||||
|
||||
// Container resizing logic
|
||||
if (resizing) {
|
||||
if (rl.isMouseButtonReleased(.left)) resizing = false;
|
||||
|
||||
const width = container.width + (mouse.x - lastMouse.x);
|
||||
container.width = if (width > minWidth) if (width < maxWidth) width else maxWidth else minWidth;
|
||||
|
||||
const height = container.height + (mouse.y - lastMouse.y);
|
||||
container.height = if (height > minHeight) if (height < maxHeight) height else maxHeight else minHeight;
|
||||
} else {
|
||||
// Check if we're resizing
|
||||
if (rl.isMouseButtonDown(.left) and rl.checkCollisionPointRec(mouse, resizer)) resizing = true;
|
||||
}
|
||||
|
||||
// Move resizer rectangle properly
|
||||
resizer.x = container.x + container.width - 17;
|
||||
resizer.y = container.y + container.height - 17;
|
||||
|
||||
lastMouse = mouse; // Update mouse
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawRectangleLinesEx(container, 3, border_color); // Draw container border
|
||||
|
||||
// Draw text in container (add some padding)
|
||||
drawTextBoxed(font, text, .{
|
||||
.x = container.x + 4,
|
||||
.y = container.y + 4,
|
||||
.width = container.width - 4,
|
||||
.height = container.height - 4,
|
||||
}, 20.0, 2.0, word_wrap, .gray);
|
||||
|
||||
rl.drawRectangleRec(resizer, border_color); // Draw the resize box
|
||||
|
||||
// Draw bottom info
|
||||
rl.drawRectangle(0, screen_height - 54, screen_width, 54, .gray);
|
||||
rl.drawRectangleRec(.{
|
||||
.x = 382.0,
|
||||
.y = screen_height - 34.0,
|
||||
.width = 12.0,
|
||||
.height = 12.0,
|
||||
}, .maroon);
|
||||
|
||||
rl.drawText("Word Wrap: ", 313, screen_height - 115, 20, .black);
|
||||
if (word_wrap) {
|
||||
rl.drawText("ON", 447, screen_height - 115, 20, .red);
|
||||
} else {
|
||||
rl.drawText("OFF", 447, screen_height - 115, 20, .black);
|
||||
}
|
||||
|
||||
rl.drawText("Press [SPACE] to toggle word wrap", 218, screen_height - 86, 20, .gray);
|
||||
|
||||
rl.drawText("Click hold & drag the to resize the container", 155, screen_height - 38, 20, .ray_white);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Module functions definition
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Draw text using font inside rectangle limits
|
||||
fn drawTextBoxed(font: rl.Font, text: [:0]const u8, rec: rl.Rectangle, font_size: f32, spacing: f32, word_wrap: bool, tint: rl.Color) void {
|
||||
drawTextBoxedSelectable(font, text, rec, font_size, spacing, word_wrap, tint, 0, 0, .white, .white);
|
||||
}
|
||||
|
||||
// Draw text using font inside rectangle limits with support for text selection
|
||||
fn drawTextBoxedSelectable(font: rl.Font, text: [:0]const u8, rec: rl.Rectangle, font_size: f32, spacing: f32, word_wrap: bool, tint: rl.Color, select_box_start: i32, select_length: i32, select_tint: rl.Color, select_back_tint: rl.Color) void {
|
||||
var select_start = select_box_start;
|
||||
const length = rl.textLength(text); // Total length in bytes of the text, scanned by codepoints in loop
|
||||
|
||||
var text_offset_y: f32 = 0; // Offset between lines (on line break '\n')
|
||||
var text_offset_x: f32 = 0.0; // Offset X to next character to draw
|
||||
|
||||
const scale_factor = font_size / @as(f32, @floatFromInt(font.baseSize)); // Character rectangle scaling factor
|
||||
|
||||
// Word/character wrapping mechanism variables
|
||||
const MeasureState = enum(u8) { measure, draw };
|
||||
var state: MeasureState = if (word_wrap) .measure else .draw;
|
||||
|
||||
var start_line: i32 = -1; // Index where to begin drawing (where a line begins)
|
||||
var end_line: i32 = -1; // Index where to stop drawing (where a line ends)
|
||||
var last_char: i32 = -1; // Holds last value of the character position
|
||||
|
||||
var i: i32 = 0;
|
||||
var k: i32 = 0;
|
||||
while (i < length) : ({
|
||||
i += 1;
|
||||
k += 1;
|
||||
}) {
|
||||
// Get next codepoint from byte string and glyph index in font
|
||||
var codepoint_byte_count: i32 = 0;
|
||||
const codepoint = rl.getCodepoint(text[@intCast(i)..], &codepoint_byte_count);
|
||||
const index: usize = @intCast(rl.getGlyphIndex(font, codepoint));
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
|
||||
if (codepoint == 0x3f) codepoint_byte_count = 1;
|
||||
i += @intCast(codepoint_byte_count - 1);
|
||||
|
||||
var glyph_width: f32 = 0;
|
||||
if (codepoint != '\n') {
|
||||
glyph_width = if (font.glyphs[index].advanceX == 0) font.recs[index].width * scale_factor else @as(f32, @floatFromInt(font.glyphs[index].advanceX)) * scale_factor;
|
||||
|
||||
if (i + 1 < length) glyph_width = glyph_width + spacing;
|
||||
}
|
||||
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container
|
||||
// We store this info in startLine and endLine, then we change states, draw the text between those two variables
|
||||
// and change states again and again recursively until the end of the text (or until we get outside of the container).
|
||||
// When wordWrap is OFF we don't need the measure state so we go to the drawing state immediately
|
||||
// and begin drawing on the next line before we can get outside the container.
|
||||
if (state == .measure) {
|
||||
// TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more
|
||||
// Ref: http://jkorpela.fi/chars/spaces.html
|
||||
if ((codepoint == ' ') or (codepoint == '\t') or (codepoint == '\n')) end_line = @intCast(i);
|
||||
|
||||
if ((text_offset_x + glyph_width) > rec.width) {
|
||||
end_line = if (end_line < 1) @intCast(i) else end_line;
|
||||
if (i == end_line) end_line -= codepoint_byte_count;
|
||||
if ((start_line + codepoint_byte_count) == end_line) end_line = @as(i32, @intCast(i)) - codepoint_byte_count;
|
||||
|
||||
state = if (state == .draw) .measure else .draw;
|
||||
} else if ((i + 1) == length) {
|
||||
end_line = @intCast(i);
|
||||
state = if (state == .draw) .measure else .draw;
|
||||
} else if (codepoint == '\n') {
|
||||
state = if (state == .draw) .measure else .draw;
|
||||
}
|
||||
|
||||
if (state == .draw) {
|
||||
text_offset_x = 0;
|
||||
i = @intCast(start_line);
|
||||
glyph_width = 0;
|
||||
|
||||
// Save character position when we switch states
|
||||
const tmp = last_char;
|
||||
last_char = k - 1;
|
||||
k = tmp;
|
||||
}
|
||||
} else {
|
||||
if (codepoint == '\n') {
|
||||
if (!word_wrap) {
|
||||
const bS: f32 = @floatFromInt(font.baseSize);
|
||||
text_offset_y += (bS + bS / 2) * scale_factor;
|
||||
text_offset_x = 0;
|
||||
}
|
||||
} else {
|
||||
if (!word_wrap and ((text_offset_x + glyph_width) > rec.width)) {
|
||||
const bS: f32 = @floatFromInt(font.baseSize);
|
||||
text_offset_y += (bS + bS / 2) * scale_factor;
|
||||
text_offset_x = 0;
|
||||
}
|
||||
|
||||
// When text overflows rectangle height limit, just stop drawing
|
||||
if ((text_offset_y + @as(f32, @floatFromInt(font.baseSize)) * scale_factor) > rec.height) break;
|
||||
|
||||
// Draw selection background
|
||||
var is_glyph_selected = false;
|
||||
if ((select_start >= 0) and (k >= select_start) and (k < (select_start + select_length))) {
|
||||
rl.drawRectangleRec(.{
|
||||
.x = rec.x + text_offset_x - 1,
|
||||
.y = rec.y + text_offset_y,
|
||||
.width = glyph_width,
|
||||
.height = @as(f32, @floatFromInt(font.baseSize)) * scale_factor,
|
||||
}, select_back_tint);
|
||||
is_glyph_selected = true;
|
||||
}
|
||||
|
||||
// Draw current character glyph
|
||||
if ((codepoint != ' ') and (codepoint != '\t')) {
|
||||
rl.drawTextCodepoint(font, codepoint, .{
|
||||
.x = rec.x + text_offset_x,
|
||||
.y = rec.y + text_offset_y,
|
||||
}, font_size, if (is_glyph_selected) select_tint else tint);
|
||||
}
|
||||
}
|
||||
|
||||
if (word_wrap and (i == end_line)) {
|
||||
const bS: f32 = @floatFromInt(font.baseSize);
|
||||
text_offset_y += (bS + bS / 2) * scale_factor;
|
||||
text_offset_x = 0;
|
||||
start_line = end_line;
|
||||
end_line = -1;
|
||||
glyph_width = 0;
|
||||
select_start += last_char - k;
|
||||
k = last_char;
|
||||
|
||||
state = if (state == .draw) .measure else .draw;
|
||||
}
|
||||
}
|
||||
|
||||
if ((text_offset_x != 0) or (codepoint != ' ')) text_offset_x += glyph_width; // avoid leading spaces
|
||||
}
|
||||
}
|
||||
BIN
examples/text/resources/DotGothic16-Regular.ttf
Normal file
BIN
examples/text/resources/KAISG.ttf
Normal file
20
examples/text/resources/LICENSE.md
Normal file
@ -0,0 +1,20 @@
|
||||
| resource | author | licence | notes |
|
||||
| :----------------------------- | :---------: | :------ | :---- |
|
||||
| fonts/alagard.png | Hewett Tsoi | [Freeware](https://www.dafont.com/es/alagard.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| fonts/romulus.png | Hewett Tsoi | [Freeware](https://www.dafont.com/es/romulus.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| fonts/alpha_beta.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/alpha-beta.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| fonts/setback.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/setback.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| fonts/jupiter_crash.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/jupiter-crash.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| fonts/mecha.png | Captain Falcon | [Freeware](https://www.dafont.com/es/mecha-cf.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| fonts/pixelplay.png | Aleksander Shevchuk | [Freeware](https://www.dafont.com/es/pixelplay.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| fonts/pixantiqua.ttf | Gerhard Großmann | [Freeware](https://www.dafont.com/es/pixantiqua.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| anonymous_pro_bold.ttf | [Mark Simonson](https://fonts.google.com/specimen/Anonymous+Pro) | [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL) | - |
|
||||
| custom_alagard.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/jupiter-crash.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| custom_jupiter_crash.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/jupiter-crash.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| custom_mecha.png | [Brian Kent (AEnigma)](https://www.dafont.com/es/aenigma.d188) | [Freeware](https://www.dafont.com/es/jupiter-crash.font) | Atlas created by [@raysan5](https://github.com/raysan5) |
|
||||
| dejavu.fnt, dejavu.png | [DejaVu Fonts](https://dejavu-fonts.github.io/) | [Free](https://dejavu-fonts.github.io/License.html) | Atlas made with [BMFont](https://www.angelcode.com/products/bmfont/) by [@raysan5](https://github.com/raysan5) |
|
||||
| KAISG.ttf | [Dieter Steffmann](http://www.steffmann.de/wordpress/) | [Freeware](https://www.1001fonts.com/users/steffmann/) | [Kaiserzeit Gotisch](https://www.dafont.com/es/kaiserzeit-gotisch.font) font |
|
||||
| noto_cjk.fnt, noto_cjk.png | [Google Fonts](https://www.google.com/get/noto/help/cjk/) | [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL) | Atlas made with [BMFont](https://www.angelcode.com/products/bmfont/) by [@raysan5](https://github.com/raysan5) |
|
||||
| pixantiqua.fnt, pixantiqua.png | Gerhard Großmann | [Freeware](https://www.dafont.com/es/pixantiqua.font) | Atlas made with [BMFont](https://www.angelcode.com/products/bmfont/) by [@raysan5](https://github.com/raysan5) |
|
||||
| pixantiqua.ttf | Gerhard Großmann | [Freeware](https://www.dafont.com/es/pixantiqua.font) | - |
|
||||
| symbola.fnt, symbola.png | George Douros | [Freeware](https://fontlibrary.org/en/font/symbola) | Atlas made with [BMFont](https://www.angelcode.com/products/bmfont/) by [@raysan5](https://github.com/raysan5) |
|
||||
BIN
examples/text/resources/anonymous_pro_bold.ttf
Normal file
BIN
examples/text/resources/custom_alagard.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
BIN
examples/text/resources/custom_jupiter_crash.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
BIN
examples/text/resources/custom_mecha.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
1115
examples/text/resources/dejavu.fnt
Normal file
BIN
examples/text/resources/dejavu.png
Normal file
|
After Width: | Height: | Size: 100 KiB |
580
examples/text/resources/noto_cjk.fnt
Normal file
@ -0,0 +1,580 @@
|
||||
info face="Noto Serif CJK JP" size=-16 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=2,2 outline=1
|
||||
common lineHeight=23 base=18 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
|
||||
page id=0 file="noto_cjk.png"
|
||||
chars count=576
|
||||
char id=32 x=507 y=185 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=4 page=0 chnl=15
|
||||
char id=33 x=449 y=285 width=5 height=14 xoffset=0 yoffset=5 xadvance=5 page=0 chnl=15
|
||||
char id=34 x=393 y=315 width=8 height=8 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=15
|
||||
char id=35 x=285 y=287 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=36 x=500 y=61 width=10 height=18 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=37 x=52 y=257 width=15 height=15 xoffset=0 yoffset=5 xadvance=15 page=0 chnl=15
|
||||
char id=38 x=495 y=268 width=14 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15
|
||||
char id=39 x=413 y=315 width=5 height=8 xoffset=-1 yoffset=4 xadvance=3 page=0 chnl=15
|
||||
char id=40 x=339 y=21 width=7 height=19 xoffset=0 yoffset=4 xadvance=6 page=0 chnl=15
|
||||
char id=41 x=330 y=21 width=7 height=19 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=15
|
||||
char id=42 x=321 y=317 width=10 height=9 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=15
|
||||
char id=43 x=26 y=322 width=11 height=11 xoffset=-1 yoffset=7 xadvance=9 page=0 chnl=15
|
||||
char id=44 x=353 y=316 width=6 height=9 xoffset=-1 yoffset=15 xadvance=5 page=0 chnl=15
|
||||
char id=45 x=136 y=334 width=7 height=4 xoffset=-1 yoffset=12 xadvance=5 page=0 chnl=15
|
||||
char id=46 x=109 y=334 width=5 height=5 xoffset=0 yoffset=14 xadvance=5 page=0 chnl=15
|
||||
char id=47 x=500 y=81 width=8 height=18 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=15
|
||||
char id=48 x=406 y=286 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=49 x=418 y=286 width=9 height=14 xoffset=0 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=50 x=394 y=286 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=51 x=382 y=286 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=52 x=272 y=287 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=53 x=370 y=286 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=54 x=358 y=286 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=55 x=346 y=286 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=56 x=334 y=287 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=57 x=322 y=287 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=58 x=502 y=300 width=5 height=11 xoffset=0 yoffset=8 xadvance=5 page=0 chnl=15
|
||||
char id=59 x=190 y=238 width=6 height=16 xoffset=-1 yoffset=8 xadvance=5 page=0 chnl=15
|
||||
char id=60 x=39 y=322 width=11 height=11 xoffset=-1 yoffset=7 xadvance=9 page=0 chnl=15
|
||||
char id=61 x=440 y=315 width=11 height=7 xoffset=-1 yoffset=9 xadvance=9 page=0 chnl=15
|
||||
char id=62 x=78 y=321 width=11 height=11 xoffset=-1 yoffset=7 xadvance=9 page=0 chnl=15
|
||||
char id=63 x=460 y=252 width=7 height=15 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=15
|
||||
char id=64 x=72 y=221 width=16 height=16 xoffset=-1 yoffset=6 xadvance=14 page=0 chnl=15
|
||||
char id=65 x=447 y=269 width=14 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15
|
||||
char id=66 x=175 y=289 width=12 height=14 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15
|
||||
char id=67 x=75 y=290 width=13 height=14 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15
|
||||
char id=68 x=415 y=270 width=14 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15
|
||||
char id=69 x=119 y=290 width=12 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15
|
||||
char id=70 x=105 y=290 width=12 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15
|
||||
char id=71 x=431 y=269 width=14 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15
|
||||
char id=72 x=302 y=271 width=15 height=14 xoffset=-1 yoffset=5 xadvance=14 page=0 chnl=15
|
||||
char id=73 x=439 y=285 width=8 height=14 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=15
|
||||
char id=74 x=268 y=200 width=9 height=17 xoffset=-2 yoffset=5 xadvance=6 page=0 chnl=15
|
||||
char id=75 x=367 y=270 width=14 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15
|
||||
char id=76 x=203 y=289 width=12 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15
|
||||
char id=77 x=158 y=273 width=17 height=14 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=78 x=285 y=271 width=15 height=14 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15
|
||||
char id=79 x=479 y=269 width=14 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15
|
||||
char id=80 x=189 y=289 width=12 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15
|
||||
char id=81 x=209 y=142 width=14 height=18 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15
|
||||
char id=82 x=30 y=291 width=13 height=14 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15
|
||||
char id=83 x=259 y=287 width=11 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=84 x=45 y=291 width=13 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15
|
||||
char id=85 x=335 y=270 width=14 height=14 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15
|
||||
char id=86 x=399 y=270 width=14 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15
|
||||
char id=87 x=485 y=252 width=19 height=14 xoffset=-1 yoffset=5 xadvance=17 page=0 chnl=15
|
||||
char id=88 x=0 y=291 width=13 height=14 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15
|
||||
char id=89 x=15 y=291 width=13 height=14 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15
|
||||
char id=90 x=217 y=287 width=12 height=14 xoffset=-1 yoffset=5 xadvance=10 page=0 chnl=15
|
||||
char id=91 x=8 y=164 width=6 height=18 xoffset=0 yoffset=4 xadvance=5 page=0 chnl=15
|
||||
char id=92 x=497 y=141 width=8 height=18 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=15
|
||||
char id=93 x=0 y=164 width=6 height=18 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=15
|
||||
char id=94 x=465 y=313 width=9 height=7 xoffset=0 yoffset=8 xadvance=9 page=0 chnl=15
|
||||
char id=95 x=145 y=334 width=11 height=3 xoffset=-1 yoffset=17 xadvance=9 page=0 chnl=15
|
||||
char id=96 x=74 y=335 width=6 height=6 xoffset=0 yoffset=4 xadvance=7 page=0 chnl=15
|
||||
char id=97 x=13 y=322 width=11 height=11 xoffset=-1 yoffset=8 xadvance=9 page=0 chnl=15
|
||||
char id=98 x=398 y=218 width=12 height=16 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15
|
||||
char id=99 x=129 y=321 width=10 height=11 xoffset=-1 yoffset=8 xadvance=8 page=0 chnl=15
|
||||
char id=100 x=426 y=217 width=12 height=16 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15
|
||||
char id=101 x=117 y=321 width=10 height=11 xoffset=-1 yoffset=8 xadvance=9 page=0 chnl=15
|
||||
char id=102 x=140 y=238 width=10 height=16 xoffset=-1 yoffset=3 xadvance=6 page=0 chnl=15
|
||||
char id=103 x=52 y=239 width=11 height=16 xoffset=-1 yoffset=8 xadvance=9 page=0 chnl=15
|
||||
char id=104 x=440 y=217 width=12 height=16 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15
|
||||
char id=105 x=469 y=252 width=7 height=15 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=15
|
||||
char id=106 x=95 y=0 width=8 height=20 xoffset=-3 yoffset=4 xadvance=5 page=0 chnl=15
|
||||
char id=107 x=412 y=218 width=12 height=16 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=108 x=451 y=252 width=7 height=15 xoffset=-1 yoffset=4 xadvance=5 page=0 chnl=15
|
||||
char id=109 x=386 y=302 width=18 height=11 xoffset=-1 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=110 x=488 y=300 width=12 height=11 xoffset=-1 yoffset=8 xadvance=11 page=0 chnl=15
|
||||
char id=111 x=91 y=321 width=11 height=11 xoffset=-1 yoffset=8 xadvance=10 page=0 chnl=15
|
||||
char id=112 x=300 y=218 width=12 height=16 xoffset=-1 yoffset=8 xadvance=10 page=0 chnl=15
|
||||
char id=113 x=286 y=219 width=12 height=16 xoffset=-1 yoffset=8 xadvance=10 page=0 chnl=15
|
||||
char id=114 x=141 y=321 width=10 height=11 xoffset=-1 yoffset=8 xadvance=7 page=0 chnl=15
|
||||
char id=115 x=165 y=320 width=9 height=11 xoffset=-1 yoffset=8 xadvance=8 page=0 chnl=15
|
||||
char id=116 x=429 y=286 width=8 height=14 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=15
|
||||
char id=117 x=474 y=300 width=12 height=11 xoffset=-1 yoffset=8 xadvance=10 page=0 chnl=15
|
||||
char id=118 x=0 y=322 width=11 height=11 xoffset=-1 yoffset=8 xadvance=9 page=0 chnl=15
|
||||
char id=119 x=424 y=302 width=16 height=11 xoffset=-1 yoffset=8 xadvance=13 page=0 chnl=15
|
||||
char id=120 x=104 y=321 width=11 height=11 xoffset=-1 yoffset=8 xadvance=9 page=0 chnl=15
|
||||
char id=121 x=342 y=218 width=12 height=16 xoffset=-2 yoffset=8 xadvance=9 page=0 chnl=15
|
||||
char id=122 x=153 y=320 width=10 height=11 xoffset=-1 yoffset=8 xadvance=8 page=0 chnl=15
|
||||
char id=123 x=467 y=141 width=8 height=18 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=15
|
||||
char id=124 x=111 y=0 width=4 height=20 xoffset=0 yoffset=4 xadvance=4 page=0 chnl=15
|
||||
char id=125 x=457 y=141 width=8 height=18 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=15
|
||||
char id=126 x=27 y=335 width=11 height=6 xoffset=-1 yoffset=9 xadvance=9 page=0 chnl=15
|
||||
char id=160 x=507 y=180 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=4 page=0 chnl=15
|
||||
char id=161 x=478 y=252 width=5 height=15 xoffset=0 yoffset=8 xadvance=5 page=0 chnl=15
|
||||
char id=162 x=430 y=252 width=10 height=15 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=163 x=310 y=287 width=10 height=14 xoffset=-1 yoffset=5 xadvance=9 page=0 chnl=15
|
||||
char id=164 x=52 y=322 width=11 height=11 xoffset=-1 yoffset=7 xadvance=9 page=0 chnl=15
|
||||
char id=165 x=201 y=305 width=12 height=13 xoffset=-2 yoffset=6 xadvance=9 page=0 chnl=15
|
||||
char id=166 x=105 y=0 width=4 height=20 xoffset=0 yoffset=4 xadvance=4 page=0 chnl=15
|
||||
char id=167 x=244 y=200 width=10 height=17 xoffset=3 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=168 x=116 y=334 width=9 height=4 xoffset=-1 yoffset=5 xadvance=7 page=0 chnl=15
|
||||
char id=169 x=251 y=271 width=15 height=14 xoffset=-1 yoffset=5 xadvance=13 page=0 chnl=15
|
||||
char id=170 x=383 y=316 width=8 height=8 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=15
|
||||
char id=171 x=248 y=317 width=10 height=10 xoffset=-1 yoffset=9 xadvance=8 page=0 chnl=15
|
||||
char id=172 x=427 y=315 width=11 height=7 xoffset=-1 yoffset=10 xadvance=9 page=0 chnl=15
|
||||
char id=173 x=127 y=334 width=7 height=4 xoffset=-1 yoffset=12 xadvance=5 page=0 chnl=15
|
||||
char id=174 x=236 y=317 width=10 height=10 xoffset=-1 yoffset=4 xadvance=8 page=0 chnl=15
|
||||
char id=175 x=158 y=333 width=7 height=3 xoffset=0 yoffset=6 xadvance=7 page=0 chnl=15
|
||||
char id=176 x=486 y=313 width=7 height=7 xoffset=-1 yoffset=5 xadvance=6 page=0 chnl=15
|
||||
char id=177 x=154 y=256 width=15 height=15 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=178 x=270 y=317 width=8 height=10 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=15
|
||||
char id=179 x=260 y=317 width=8 height=10 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=15
|
||||
char id=180 x=58 y=335 width=6 height=6 xoffset=1 yoffset=4 xadvance=7 page=0 chnl=15
|
||||
char id=181 x=26 y=240 width=11 height=16 xoffset=0 yoffset=7 xadvance=10 page=0 chnl=15
|
||||
char id=182 x=216 y=200 width=12 height=17 xoffset=2 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=183 x=102 y=334 width=5 height=5 xoffset=0 yoffset=10 xadvance=5 page=0 chnl=15
|
||||
char id=184 x=504 y=313 width=6 height=7 xoffset=0 yoffset=16 xadvance=7 page=0 chnl=15
|
||||
char id=185 x=280 y=317 width=7 height=10 xoffset=0 yoffset=2 xadvance=6 page=0 chnl=15
|
||||
char id=186 x=403 y=315 width=8 height=8 xoffset=-1 yoffset=4 xadvance=6 page=0 chnl=15
|
||||
char id=187 x=224 y=320 width=10 height=10 xoffset=-1 yoffset=9 xadvance=8 page=0 chnl=15
|
||||
char id=188 x=137 y=256 width=15 height=15 xoffset=0 yoffset=5 xadvance=15 page=0 chnl=15
|
||||
char id=189 x=375 y=236 width=16 height=15 xoffset=-1 yoffset=5 xadvance=15 page=0 chnl=15
|
||||
char id=190 x=120 y=256 width=15 height=15 xoffset=0 yoffset=5 xadvance=15 page=0 chnl=15
|
||||
char id=191 x=442 y=252 width=7 height=15 xoffset=0 yoffset=8 xadvance=7 page=0 chnl=15
|
||||
char id=192 x=273 y=142 width=14 height=18 xoffset=-1 yoffset=1 xadvance=12 page=0 chnl=15
|
||||
char id=193 x=353 y=142 width=14 height=18 xoffset=-1 yoffset=1 xadvance=12 page=0 chnl=15
|
||||
char id=194 x=48 y=202 width=14 height=17 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15
|
||||
char id=195 x=337 y=142 width=14 height=18 xoffset=-1 yoffset=1 xadvance=12 page=0 chnl=15
|
||||
char id=196 x=0 y=203 width=14 height=17 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15
|
||||
char id=197 x=225 y=142 width=14 height=18 xoffset=-1 yoffset=1 xadvance=12 page=0 chnl=15
|
||||
char id=198 x=20 y=275 width=18 height=14 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=199 x=400 y=141 width=13 height=18 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15
|
||||
char id=200 x=443 y=141 width=12 height=18 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15
|
||||
char id=201 x=498 y=101 width=12 height=18 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15
|
||||
char id=202 x=429 y=141 width=12 height=18 xoffset=-1 yoffset=1 xadvance=10 page=0 chnl=15
|
||||
char id=203 x=202 y=200 width=12 height=17 xoffset=-1 yoffset=2 xadvance=10 page=0 chnl=15
|
||||
char id=204 x=502 y=121 width=8 height=18 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=15
|
||||
char id=205 x=477 y=141 width=8 height=18 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=15
|
||||
char id=206 x=487 y=141 width=8 height=18 xoffset=-1 yoffset=1 xadvance=6 page=0 chnl=15
|
||||
char id=207 x=279 y=200 width=8 height=17 xoffset=-1 yoffset=2 xadvance=6 page=0 chnl=15
|
||||
char id=208 x=319 y=271 width=14 height=14 xoffset=-1 yoffset=5 xadvance=12 page=0 chnl=15
|
||||
char id=209 x=142 y=143 width=15 height=18 xoffset=-1 yoffset=1 xadvance=13 page=0 chnl=15
|
||||
char id=210 x=305 y=142 width=14 height=18 xoffset=-1 yoffset=1 xadvance=12 page=0 chnl=15
|
||||
char id=211 x=369 y=142 width=14 height=18 xoffset=-1 yoffset=1 xadvance=12 page=0 chnl=15
|
||||
char id=212 x=491 y=180 width=14 height=17 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15
|
||||
char id=213 x=475 y=180 width=14 height=17 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15
|
||||
char id=214 x=96 y=201 width=14 height=17 xoffset=-1 yoffset=2 xadvance=12 page=0 chnl=15
|
||||
char id=215 x=173 y=305 width=12 height=13 xoffset=2 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=216 x=209 y=219 width=14 height=16 xoffset=-1 yoffset=4 xadvance=12 page=0 chnl=15
|
||||
char id=217 x=241 y=142 width=14 height=18 xoffset=-1 yoffset=1 xadvance=13 page=0 chnl=15
|
||||
char id=218 x=257 y=142 width=14 height=18 xoffset=-1 yoffset=1 xadvance=13 page=0 chnl=15
|
||||
char id=219 x=64 y=202 width=14 height=17 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15
|
||||
char id=220 x=16 y=203 width=14 height=17 xoffset=-1 yoffset=2 xadvance=13 page=0 chnl=15
|
||||
char id=221 x=385 y=141 width=13 height=18 xoffset=-1 yoffset=1 xadvance=11 page=0 chnl=15
|
||||
char id=222 x=231 y=287 width=12 height=14 xoffset=-1 yoffset=5 xadvance=11 page=0 chnl=15
|
||||
char id=223 x=299 y=254 width=12 height=15 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=15
|
||||
char id=224 x=13 y=240 width=11 height=16 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=225 x=0 y=240 width=11 height=16 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=226 x=493 y=217 width=11 height=16 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=227 x=367 y=253 width=11 height=15 xoffset=-1 yoffset=4 xadvance=9 page=0 chnl=15
|
||||
char id=228 x=341 y=253 width=11 height=15 xoffset=-1 yoffset=4 xadvance=9 page=0 chnl=15
|
||||
char id=229 x=480 y=217 width=11 height=16 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=230 x=442 y=301 width=15 height=11 xoffset=-1 yoffset=8 xadvance=14 page=0 chnl=15
|
||||
char id=231 x=406 y=253 width=10 height=15 xoffset=-1 yoffset=8 xadvance=8 page=0 chnl=15
|
||||
char id=232 x=116 y=238 width=10 height=16 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=233 x=128 y=238 width=10 height=16 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=234 x=104 y=239 width=10 height=16 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=235 x=418 y=253 width=10 height=15 xoffset=-1 yoffset=4 xadvance=9 page=0 chnl=15
|
||||
char id=236 x=172 y=238 width=7 height=16 xoffset=-1 yoffset=3 xadvance=5 page=0 chnl=15
|
||||
char id=237 x=181 y=238 width=7 height=16 xoffset=-1 yoffset=3 xadvance=5 page=0 chnl=15
|
||||
char id=238 x=163 y=238 width=7 height=16 xoffset=-1 yoffset=3 xadvance=5 page=0 chnl=15
|
||||
char id=239 x=501 y=235 width=9 height=15 xoffset=-2 yoffset=4 xadvance=5 page=0 chnl=15
|
||||
char id=240 x=454 y=217 width=11 height=16 xoffset=-1 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=241 x=327 y=253 width=12 height=15 xoffset=-1 yoffset=4 xadvance=11 page=0 chnl=15
|
||||
char id=242 x=91 y=239 width=11 height=16 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15
|
||||
char id=243 x=78 y=239 width=11 height=16 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15
|
||||
char id=244 x=65 y=239 width=11 height=16 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15
|
||||
char id=245 x=393 y=253 width=11 height=15 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=15
|
||||
char id=246 x=380 y=253 width=11 height=15 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=15
|
||||
char id=247 x=233 y=271 width=16 height=14 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=248 x=215 y=305 width=11 height=13 xoffset=-1 yoffset=7 xadvance=10 page=0 chnl=15
|
||||
char id=249 x=384 y=218 width=12 height=16 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15
|
||||
char id=250 x=356 y=218 width=12 height=16 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15
|
||||
char id=251 x=314 y=218 width=12 height=16 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15
|
||||
char id=252 x=313 y=254 width=12 height=15 xoffset=-1 yoffset=4 xadvance=10 page=0 chnl=15
|
||||
char id=253 x=0 y=0 width=12 height=21 xoffset=-2 yoffset=3 xadvance=9 page=0 chnl=15
|
||||
char id=254 x=14 y=0 width=11 height=21 xoffset=-1 yoffset=3 xadvance=10 page=0 chnl=15
|
||||
char id=255 x=81 y=0 width=12 height=20 xoffset=-2 yoffset=4 xadvance=9 page=0 chnl=15
|
||||
char id=8220 x=361 y=316 width=9 height=8 xoffset=-1 yoffset=4 xadvance=7 page=0 chnl=15
|
||||
char id=8222 x=372 y=316 width=9 height=8 xoffset=-1 yoffset=14 xadvance=7 page=0 chnl=15
|
||||
char id=9829 x=18 y=222 width=16 height=16 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12288 x=507 y=141 width=3 height=3 xoffset=-1 yoffset=-1 xadvance=16 page=0 chnl=15
|
||||
char id=12290 x=476 y=313 width=8 height=7 xoffset=-1 yoffset=14 xadvance=16 page=0 chnl=15
|
||||
char id=12353 x=147 y=289 width=12 height=14 xoffset=2 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12354 x=73 y=183 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12355 x=459 y=300 width=13 height=11 xoffset=1 yoffset=9 xadvance=16 page=0 chnl=15
|
||||
char id=12356 x=483 y=235 width=16 height=15 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12357 x=298 y=287 width=10 height=14 xoffset=3 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12358 x=415 y=141 width=12 height=18 xoffset=2 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12359 x=187 y=305 width=12 height=13 xoffset=2 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12360 x=409 y=180 width=15 height=17 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12361 x=53 y=307 width=14 height=13 xoffset=1 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=12362 x=108 y=220 width=16 height=16 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12363 x=271 y=181 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12364 x=0 y=184 width=17 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12365 x=32 y=202 width=14 height=17 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12366 x=72 y=143 width=16 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12367 x=152 y=238 width=9 height=16 xoffset=3 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12368 x=256 y=219 width=13 height=16 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12369 x=375 y=181 width=15 height=17 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12370 x=340 y=122 width=16 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12371 x=284 y=254 width=13 height=15 xoffset=2 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12372 x=426 y=180 width=15 height=17 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12373 x=142 y=201 width=13 height=17 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12374 x=57 y=123 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12375 x=443 y=180 width=14 height=17 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12376 x=112 y=201 width=13 height=17 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12377 x=235 y=181 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12378 x=209 y=122 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12379 x=309 y=200 width=18 height=16 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12380 x=137 y=163 width=18 height=17 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12381 x=358 y=181 width=15 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12382 x=396 y=161 width=17 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12383 x=217 y=181 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12384 x=277 y=162 width=18 height=17 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12385 x=324 y=181 width=15 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12386 x=430 y=121 width=16 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12387 x=195 y=320 width=13 height=10 xoffset=1 yoffset=10 xadvance=16 page=0 chnl=15
|
||||
char id=12388 x=267 y=303 width=17 height=12 xoffset=-1 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12389 x=218 y=237 width=18 height=15 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12390 x=411 y=236 width=16 height=15 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12391 x=338 y=236 width=17 height=15 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12392 x=370 y=218 width=12 height=16 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12393 x=392 y=181 width=15 height=17 xoffset=2 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12394 x=477 y=199 width=16 height=16 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12395 x=160 y=220 width=15 height=16 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12396 x=447 y=235 width=16 height=15 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12397 x=491 y=161 width=17 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12398 x=465 y=235 width=16 height=15 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12399 x=36 y=221 width=16 height=16 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12400 x=479 y=101 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12401 x=247 y=122 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12402 x=495 y=199 width=15 height=16 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12403 x=36 y=144 width=16 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12404 x=253 y=181 width=16 height=17 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12405 x=348 y=200 width=17 height=16 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12406 x=289 y=200 width=18 height=16 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12407 x=386 y=200 width=17 height=16 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12408 x=228 y=303 width=18 height=12 xoffset=-1 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12409 x=139 y=273 width=17 height=14 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12410 x=456 y=285 width=17 height=13 xoffset=-1 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12411 x=55 y=183 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12412 x=171 y=122 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12413 x=95 y=123 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12414 x=193 y=219 width=14 height=16 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12415 x=405 y=200 width=16 height=16 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12416 x=367 y=200 width=17 height=16 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12417 x=90 y=221 width=16 height=16 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12418 x=328 y=218 width=12 height=16 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12419 x=383 y=270 width=14 height=14 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12420 x=472 y=161 width=17 height=17 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12421 x=159 y=305 width=12 height=13 xoffset=2 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=12422 x=109 y=182 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12423 x=348 y=302 width=11 height=12 xoffset=3 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=12424 x=241 y=219 width=13 height=16 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12425 x=127 y=201 width=13 height=17 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12426 x=500 y=41 width=10 height=18 xoffset=3 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12427 x=188 y=256 width=14 height=15 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12428 x=177 y=162 width=18 height=17 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12429 x=177 y=220 width=14 height=16 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12430 x=351 y=270 width=14 height=14 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12431 x=163 y=182 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12432 x=393 y=236 width=16 height=15 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12433 x=181 y=181 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12434 x=143 y=220 width=15 height=16 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12435 x=54 y=221 width=16 height=16 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12436 x=289 y=142 width=14 height=18 xoffset=2 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12437 x=463 y=269 width=14 height=14 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12438 x=101 y=306 width=13 height=13 xoffset=2 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=12441 x=40 y=335 width=7 height=6 xoffset=-6 yoffset=3 xadvance=0 page=0 chnl=15
|
||||
char id=12442 x=49 y=335 width=7 height=6 xoffset=-5 yoffset=3 xadvance=0 page=0 chnl=15
|
||||
char id=12443 x=495 y=313 width=7 height=7 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12444 x=0 y=335 width=7 height=7 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12445 x=333 y=317 width=8 height=9 xoffset=4 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=12446 x=65 y=322 width=11 height=11 xoffset=4 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12447 x=193 y=142 width=14 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12448 x=453 y=314 width=10 height=7 xoffset=3 yoffset=9 xadvance=16 page=0 chnl=15
|
||||
char id=12449 x=334 y=303 width=12 height=12 xoffset=2 yoffset=9 xadvance=16 page=0 chnl=15
|
||||
char id=12450 x=126 y=220 width=15 height=16 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12451 x=374 y=302 width=10 height=12 xoffset=2 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=12452 x=157 y=201 width=13 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12453 x=161 y=289 width=12 height=14 xoffset=2 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12454 x=459 y=180 width=14 height=17 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12455 x=289 y=317 width=14 height=9 xoffset=1 yoffset=10 xadvance=16 page=0 chnl=15
|
||||
char id=12456 x=494 y=285 width=16 height=13 xoffset=0 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12457 x=116 y=306 width=13 height=13 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12458 x=459 y=199 width=16 height=16 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12459 x=307 y=181 width=15 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12460 x=453 y=161 width=17 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12461 x=289 y=181 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12462 x=285 y=122 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12463 x=80 y=202 width=14 height=17 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12464 x=448 y=121 width=16 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12465 x=0 y=222 width=16 height=16 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12466 x=19 y=124 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12467 x=304 y=303 width=14 height=12 xoffset=1 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12468 x=429 y=235 width=16 height=15 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12469 x=199 y=181 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12470 x=160 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12471 x=103 y=257 width=15 height=15 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12472 x=341 y=181 width=15 height=17 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12473 x=69 y=257 width=15 height=15 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12474 x=145 y=182 width=16 height=17 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12475 x=86 y=257 width=15 height=15 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12476 x=278 y=237 width=18 height=15 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12477 x=204 y=254 width=14 height=15 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12478 x=322 y=122 width=16 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12479 x=321 y=142 width=14 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12480 x=38 y=124 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12481 x=127 y=182 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12482 x=434 y=161 width=17 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12483 x=320 y=303 width=12 height=12 xoffset=2 yoffset=9 xadvance=16 page=0 chnl=15
|
||||
char id=12484 x=252 y=254 width=14 height=15 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12485 x=266 y=122 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12486 x=441 y=199 width=16 height=16 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12487 x=228 y=122 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12488 x=256 y=200 width=10 height=17 xoffset=4 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12489 x=230 y=200 width=12 height=17 xoffset=3 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12490 x=91 y=182 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12491 x=406 y=302 width=16 height=11 xoffset=0 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12492 x=35 y=258 width=15 height=15 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12493 x=484 y=121 width=16 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12494 x=90 y=290 width=13 height=14 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12495 x=176 y=320 width=17 height=10 xoffset=-1 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=12496 x=196 y=273 width=17 height=14 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12497 x=177 y=273 width=17 height=14 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12498 x=60 y=290 width=13 height=14 xoffset=2 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12499 x=171 y=256 width=15 height=15 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12500 x=0 y=258 width=16 height=15 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12501 x=236 y=254 width=14 height=15 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12502 x=18 y=144 width=16 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12503 x=90 y=143 width=16 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12504 x=248 y=303 width=17 height=12 xoffset=-1 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12505 x=120 y=273 width=17 height=14 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12506 x=475 y=285 width=17 height=13 xoffset=-1 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12507 x=357 y=236 width=16 height=15 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12508 x=415 y=161 width=17 height=17 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12509 x=37 y=183 width=16 height=17 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12510 x=286 y=303 width=16 height=12 xoffset=0 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12511 x=354 y=253 width=11 height=15 xoffset=2 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12512 x=18 y=258 width=15 height=15 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12513 x=268 y=254 width=14 height=15 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12514 x=215 y=271 width=16 height=14 xoffset=0 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12515 x=131 y=306 width=12 height=13 xoffset=2 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=12516 x=423 y=199 width=16 height=16 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12517 x=305 y=317 width=14 height=9 xoffset=1 yoffset=10 xadvance=16 page=0 chnl=15
|
||||
char id=12518 x=0 y=307 width=16 height=13 xoffset=0 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12519 x=210 y=320 width=12 height=10 xoffset=2 yoffset=9 xadvance=16 page=0 chnl=15
|
||||
char id=12520 x=85 y=306 width=14 height=13 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12521 x=225 y=219 width=14 height=16 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12522 x=39 y=239 width=11 height=16 xoffset=2 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12523 x=0 y=275 width=18 height=14 xoffset=-1 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12524 x=36 y=307 width=15 height=13 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12525 x=69 y=306 width=14 height=13 xoffset=1 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12526 x=145 y=305 width=12 height=13 xoffset=2 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=12527 x=220 y=254 width=14 height=15 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12528 x=19 y=183 width=16 height=17 xoffset=0 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=12529 x=18 y=307 width=16 height=13 xoffset=0 yoffset=6 xadvance=16 page=0 chnl=15
|
||||
char id=12530 x=271 y=219 width=13 height=16 xoffset=2 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12531 x=268 y=271 width=15 height=14 xoffset=1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12532 x=304 y=122 width=16 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12533 x=133 y=289 width=12 height=14 xoffset=2 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12534 x=245 y=287 width=12 height=14 xoffset=2 yoffset=7 xadvance=16 page=0 chnl=15
|
||||
char id=12535 x=190 y=122 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12536 x=140 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12537 x=329 y=200 width=17 height=16 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12538 x=54 y=144 width=16 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=12539 x=66 y=335 width=6 height=6 xoffset=5 yoffset=10 xadvance=16 page=0 chnl=15
|
||||
char id=12540 x=9 y=335 width=16 height=6 xoffset=0 yoffset=10 xadvance=16 page=0 chnl=15
|
||||
char id=12541 x=343 y=317 width=8 height=9 xoffset=4 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=12542 x=361 y=302 width=11 height=12 xoffset=4 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=12543 x=172 y=201 width=13 height=17 xoffset=1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=19968 x=82 y=334 width=18 height=5 xoffset=-1 yoffset=8 xadvance=16 page=0 chnl=15
|
||||
char id=19975 x=217 y=162 width=18 height=17 xoffset=-1 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=19979 x=120 y=103 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=19981 x=100 y=103 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20037 x=80 y=103 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20096 x=60 y=103 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20102 x=394 y=121 width=16 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20107 x=40 y=103 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20108 x=60 y=274 width=18 height=14 xoffset=-1 yoffset=5 xadvance=16 page=0 chnl=15
|
||||
char id=20154 x=20 y=104 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20260 x=0 y=104 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20307 x=480 y=81 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20316 x=320 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20320 x=340 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20663 x=320 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20814 x=120 y=63 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20837 x=80 y=63 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20853 x=60 y=63 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20891 x=40 y=63 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20986 x=0 y=144 width=16 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=20999 x=480 y=41 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=21040 x=460 y=41 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=21147 x=133 y=123 width=17 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=21151 x=440 y=41 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=21315 x=420 y=41 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=21507 x=377 y=162 width=17 height=17 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=21527 x=152 y=122 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=21534 x=400 y=41 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=21705 x=380 y=41 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=22622 x=360 y=41 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=22825 x=340 y=42 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=22833 x=260 y=42 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=22836 x=220 y=42 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=22909 x=160 y=42 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=23376 x=140 y=42 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=23398 x=120 y=43 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=23544 x=80 y=43 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=23558 x=60 y=43 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=24120 x=40 y=43 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=24180 x=117 y=0 width=18 height=19 xoffset=-1 yoffset=2 xadvance=16 page=0 chnl=15
|
||||
char id=24320 x=20 y=44 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=24433 x=0 y=44 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=24471 x=469 y=21 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=24515 x=16 y=164 width=19 height=17 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=24605 x=197 y=162 width=18 height=17 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=24651 x=357 y=162 width=18 height=17 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=25105 x=449 y=21 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=26080 x=409 y=21 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=26082 x=369 y=21 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=26085 x=187 y=200 width=13 height=17 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
char id=26131 x=457 y=0 width=17 height=19 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=26178 x=0 y=124 width=17 height=18 xoffset=0 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=26368 x=440 y=101 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=26377 x=420 y=101 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=26408 x=400 y=101 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=26543 x=380 y=101 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=27493 x=360 y=101 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=27515 x=340 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=27714 x=320 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=27835 x=300 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=27963 x=280 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=28937 x=260 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=29483 x=240 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=29503 x=220 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=29627 x=200 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=29702 x=157 y=163 width=18 height=17 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=29827 x=180 y=102 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=30002 x=159 y=142 width=15 height=18 xoffset=1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=30045 x=460 y=81 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=30693 x=440 y=81 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=31119 x=420 y=81 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=31169 x=348 y=21 width=19 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=31348 x=400 y=81 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=32299 x=380 y=81 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=32368 x=360 y=81 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=32705 x=340 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=32769 x=257 y=162 width=18 height=17 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=32773 x=300 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=32780 x=280 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=32988 x=260 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=32993 x=240 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=33021 x=220 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=33853 x=200 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=34382 x=180 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=34678 x=160 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=34892 x=140 y=82 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=35265 x=120 y=83 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=35328 x=100 y=83 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=36208 x=80 y=83 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=36335 x=60 y=83 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=36523 x=40 y=83 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=36817 x=20 y=84 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=36820 x=0 y=84 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=36861 x=480 y=61 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=36941 x=460 y=61 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=36965 x=440 y=61 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=37326 x=420 y=61 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=38590 x=400 y=61 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=38750 x=380 y=61 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=39034 x=360 y=61 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=39118 x=300 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=39135 x=280 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=39340 x=260 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=39532 x=240 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=39543 x=220 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=40575 x=200 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=40614 x=180 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=16 page=0 chnl=15
|
||||
char id=44040 x=160 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=44049 x=357 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=44057 x=140 y=62 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=44060 x=19 y=23 width=16 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=44163 x=145 y=21 width=16 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=44221 x=412 y=121 width=16 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=44256 x=238 y=237 width=18 height=15 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=44397 x=237 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=44536 x=80 y=274 width=18 height=14 xoffset=-1 yoffset=5 xadvance=15 page=0 chnl=15
|
||||
char id=44544 x=100 y=63 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=44592 x=282 y=21 width=14 height=19 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=45033 x=466 y=121 width=16 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=45149 x=237 y=162 width=18 height=17 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=45208 x=437 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=45209 x=0 y=23 width=17 height=19 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=45212 x=20 y=64 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=45216 x=0 y=64 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=45320 x=198 y=21 width=15 height=19 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=45328 x=176 y=142 width=15 height=18 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=45397 x=495 y=0 width=15 height=19 xoffset=0 yoffset=2 xadvance=15 page=0 chnl=15
|
||||
char id=45576 x=297 y=162 width=18 height=17 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=45716 x=317 y=162 width=18 height=17 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=45720 x=337 y=162 width=18 height=17 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=45768 x=266 y=21 width=14 height=19 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=45796 x=27 y=0 width=18 height=20 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15
|
||||
char id=46020 x=40 y=275 width=18 height=14 xoffset=-1 yoffset=5 xadvance=15 page=0 chnl=15
|
||||
char id=46024 x=117 y=163 width=18 height=17 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=46160 x=320 y=42 width=18 height=18 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=46301 x=300 y=42 width=18 height=18 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=46384 x=257 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=46972 x=197 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=46976 x=280 y=42 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=47000 x=163 y=21 width=16 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=47196 x=258 y=237 width=18 height=15 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=47336 x=240 y=42 width=18 height=18 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=47476 x=298 y=237 width=18 height=15 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=47484 x=97 y=163 width=18 height=17 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=47532 x=65 y=0 width=14 height=20 xoffset=0 yoffset=2 xadvance=15 page=0 chnl=15
|
||||
char id=47560 x=277 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=47564 x=200 y=42 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=47568 x=180 y=42 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=47588 x=127 y=21 width=16 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=47673 x=181 y=21 width=15 height=19 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=47784 x=318 y=236 width=18 height=15 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=48148 x=297 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=48152 x=317 y=0 width=18 height=19 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15
|
||||
char id=48373 x=217 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=49373 x=376 y=121 width=16 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=49436 x=73 y=22 width=16 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=49464 x=55 y=22 width=16 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=49688 x=377 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=49845 x=397 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=49884 x=125 y=143 width=15 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=49892 x=358 y=122 width=16 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=50420 x=100 y=43 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=50500 x=417 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=50504 x=114 y=123 width=17 height=18 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=50506 x=460 y=101 width=17 height=18 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=50508 x=76 y=123 width=17 height=18 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=50612 x=215 y=21 width=15 height=19 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=50631 x=249 y=21 width=15 height=19 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=50640 x=47 y=0 width=16 height=20 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15
|
||||
char id=50728 x=77 y=163 width=18 height=17 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=50836 x=198 y=237 width=18 height=15 xoffset=-1 yoffset=5 xadvance=15 page=0 chnl=15
|
||||
char id=50857 x=57 y=164 width=18 height=17 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=50948 x=37 y=22 width=16 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=50976 x=489 y=21 width=18 height=18 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=51012 x=37 y=164 width=18 height=17 xoffset=-1 yoffset=4 xadvance=15 page=0 chnl=15
|
||||
char id=51060 x=298 y=21 width=14 height=19 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=51080 x=91 y=22 width=16 height=19 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=51088 x=337 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=51228 x=109 y=22 width=16 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=51460 x=429 y=21 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=51648 x=232 y=21 width=15 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=51652 x=108 y=143 width=15 height=18 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=52380 x=476 y=0 width=17 height=19 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15
|
||||
char id=52840 x=314 y=21 width=14 height=19 xoffset=0 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=54032 x=389 y=21 width=18 height=18 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=54532 x=100 y=274 width=18 height=14 xoffset=-1 yoffset=5 xadvance=15 page=0 chnl=15
|
||||
char id=54616 x=177 y=0 width=18 height=19 xoffset=-1 yoffset=3 xadvance=15 page=0 chnl=15
|
||||
char id=54620 x=157 y=0 width=18 height=19 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15
|
||||
char id=54988 x=137 y=0 width=18 height=19 xoffset=-1 yoffset=2 xadvance=15 page=0 chnl=15
|
||||
char id=65292 x=420 y=315 width=5 height=8 xoffset=0 yoffset=15 xadvance=16 page=0 chnl=15
|
||||
char id=65311 x=467 y=217 width=11 height=16 xoffset=2 yoffset=4 xadvance=16 page=0 chnl=15
|
||||
BIN
examples/text/resources/noto_cjk.png
Normal file
|
After Width: | Height: | Size: 90 KiB |
188
examples/text/resources/pixantiqua.fnt
Normal file
@ -0,0 +1,188 @@
|
||||
info face="PixAntiqua" size=32 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=2,2,2,2 spacing=2,2 outline=0
|
||||
common lineHeight=32 base=27 scaleW=512 scaleH=512 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
|
||||
page id=0 file="pixantiqua.png"
|
||||
chars count=184
|
||||
char id=32 x=9 y=304 width=7 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=33 x=391 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=34 x=240 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=35 x=468 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=36 x=152 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=37 x=176 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=38 x=303 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=39 x=495 y=266 width=8 height=36 xoffset=-3 yoffset=-2 xadvance=5 page=0 chnl=15
|
||||
char id=40 x=256 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=199 x=432 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=200 x=126 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=201 x=147 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=202 x=288 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=203 x=189 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=204 x=468 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=205 x=486 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=206 x=0 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=207 x=72 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=208 x=329 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=209 x=277 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=210 x=182 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=211 x=26 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=41 x=272 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=42 x=288 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=43 x=414 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=44 x=378 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=45 x=414 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=46 x=443 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=47 x=392 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=48 x=485 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=49 x=450 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=50 x=21 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=51 x=42 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=59 x=456 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=60 x=168 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=61 x=309 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=62 x=336 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=63 x=315 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=64 x=364 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=65 x=390 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=66 x=120 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=67 x=144 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=68 x=168 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=69 x=294 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=52 x=488 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=53 x=63 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=54 x=24 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=55 x=48 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=56 x=72 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=57 x=96 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=58 x=404 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=70 x=252 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=71 x=192 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=72 x=78 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=78 x=78 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=79 x=355 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=80 x=264 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=81 x=381 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=82 x=288 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=83 x=312 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=91 x=144 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=92 x=108 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=93 x=304 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=94 x=34 y=0 width=32 height=36 xoffset=-3 yoffset=-2 xadvance=29 page=0 chnl=15
|
||||
char id=95 x=231 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=96 x=442 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=97 x=408 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=98 x=432 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=99 x=210 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=84 x=336 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=85 x=360 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=86 x=0 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=87 x=68 y=0 width=30 height=36 xoffset=-3 yoffset=-2 xadvance=27 page=0 chnl=15
|
||||
char id=88 x=26 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=89 x=384 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=90 x=84 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=100 x=456 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=101 x=480 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=102 x=54 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=103 x=0 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=104 x=24 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=105 x=469 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=106 x=18 y=266 width=16 height=36 xoffset=-8 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=107 x=48 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=108 x=417 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=109 x=161 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15
|
||||
char id=110 x=72 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=111 x=96 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=117 x=192 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=118 x=216 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=119 x=248 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15
|
||||
char id=120 x=240 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=121 x=264 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=122 x=288 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=123 x=432 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=124 x=365 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=125 x=378 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=126 x=393 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=127 x=132 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15
|
||||
char id=160 x=0 y=304 width=7 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=161 x=352 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=162 x=351 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=163 x=336 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=165 x=360 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=167 x=384 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=169 x=433 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=170 x=224 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=171 x=105 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=172 x=0 y=0 width=32 height=36 xoffset=-3 yoffset=-2 xadvance=29 page=0 chnl=15
|
||||
char id=173 x=494 y=38 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=174 x=52 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=175 x=52 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=176 x=126 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=177 x=435 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=178 x=320 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=179 x=336 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=181 x=459 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=112 x=120 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=113 x=144 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=114 x=396 y=228 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=115 x=168 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=116 x=36 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=182 x=408 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=183 x=498 y=190 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=185 x=192 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=186 x=208 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=187 x=477 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=191 x=456 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=192 x=407 y=0 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=193 x=234 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=194 x=416 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=195 x=156 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=196 x=130 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=197 x=104 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=198 x=190 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15
|
||||
char id=212 x=0 y=76 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=213 x=338 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=214 x=312 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=215 x=357 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=216 x=286 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=217 x=456 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=218 x=480 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=219 x=0 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=220 x=24 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=221 x=48 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=222 x=260 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=223 x=72 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=224 x=96 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=225 x=120 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=226 x=144 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=227 x=168 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=228 x=192 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=229 x=216 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=230 x=219 y=0 width=27 height=36 xoffset=-3 yoffset=-2 xadvance=24 page=0 chnl=15
|
||||
char id=231 x=372 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=73 x=90 y=266 width=16 height=36 xoffset=-3 yoffset=-2 xadvance=13 page=0 chnl=15
|
||||
char id=74 x=216 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=75 x=240 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=76 x=273 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=77 x=100 y=0 width=30 height=36 xoffset=-3 yoffset=-2 xadvance=27 page=0 chnl=15
|
||||
char id=232 x=312 y=152 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=233 x=240 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=234 x=264 y=190 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=235 x=104 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=236 x=430 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=237 x=482 y=266 width=11 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=238 x=160 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=11 page=0 chnl=15
|
||||
char id=239 x=176 y=266 width=14 height=36 xoffset=-3 yoffset=-2 xadvance=8 page=0 chnl=15
|
||||
char id=240 x=128 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=241 x=200 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=242 x=224 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=243 x=248 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=244 x=272 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=245 x=296 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=246 x=320 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=247 x=330 y=190 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=248 x=208 y=38 width=24 height=36 xoffset=-3 yoffset=-2 xadvance=21 page=0 chnl=15
|
||||
char id=249 x=344 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=250 x=368 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=251 x=416 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=252 x=440 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=253 x=464 y=76 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
char id=254 x=0 y=228 width=19 height=36 xoffset=-3 yoffset=-2 xadvance=16 page=0 chnl=15
|
||||
char id=255 x=0 y=114 width=22 height=36 xoffset=-3 yoffset=-2 xadvance=19 page=0 chnl=15
|
||||
BIN
examples/text/resources/pixantiqua.png
Normal file
|
After Width: | Height: | Size: 4.4 KiB |
BIN
examples/text/resources/pixantiqua.ttf
Normal file
20
examples/text/resources/shaders/glsl100/alpha_discard.fs
Normal file
@ -0,0 +1,20 @@
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texelColor = texture2D(texture0, fragTexCoord);
|
||||
|
||||
if (texelColor.a == 0.0) discard;
|
||||
|
||||
gl_FragColor = texelColor*fragColor*colDiffuse;
|
||||
}
|
||||
25
examples/text/resources/shaders/glsl100/sdf.fs
Normal file
@ -0,0 +1,25 @@
|
||||
#version 100
|
||||
|
||||
precision mediump float;
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
varying vec2 fragTexCoord;
|
||||
varying vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
const float smoothing = 1.0/16.0;
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
// NOTE: Calculate alpha using signed distance field (SDF)
|
||||
float distance = texture2D(texture0, fragTexCoord).a;
|
||||
float alpha = smoothstep(0.5 - smoothing, 0.5 + smoothing, distance);
|
||||
|
||||
// Calculate final fragment color
|
||||
gl_FragColor = vec4(fragColor.rgb, fragColor.a*alpha);
|
||||
}
|
||||
19
examples/text/resources/shaders/glsl330/alpha_discard.fs
Normal file
@ -0,0 +1,19 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 texelColor = texture(texture0, fragTexCoord);
|
||||
if (texelColor.a == 0.0) discard;
|
||||
finalColor = texelColor * fragColor * colDiffuse;
|
||||
}
|
||||
26
examples/text/resources/shaders/glsl330/sdf.fs
Normal file
@ -0,0 +1,26 @@
|
||||
#version 330
|
||||
|
||||
// Input vertex attributes (from vertex shader)
|
||||
in vec2 fragTexCoord;
|
||||
in vec4 fragColor;
|
||||
|
||||
// Input uniform values
|
||||
uniform sampler2D texture0;
|
||||
uniform vec4 colDiffuse;
|
||||
|
||||
// Output fragment color
|
||||
out vec4 finalColor;
|
||||
|
||||
// NOTE: Add your custom variables here
|
||||
|
||||
void main()
|
||||
{
|
||||
// Texel color fetching from texture sampler
|
||||
// NOTE: Calculate alpha using signed distance field (SDF)
|
||||
float distanceFromOutline = texture(texture0, fragTexCoord).a - 0.5;
|
||||
float distanceChangePerFragment = length(vec2(dFdx(distanceFromOutline), dFdy(distanceFromOutline)));
|
||||
float alpha = smoothstep(-distanceChangePerFragment, distanceChangePerFragment, distanceFromOutline);
|
||||
|
||||
// Calculate final fragment color
|
||||
finalColor = vec4(fragColor.rgb, fragColor.a*alpha);
|
||||
}
|
||||
191
examples/text/resources/symbola.fnt
Normal file
@ -0,0 +1,191 @@
|
||||
info face="Symbola" size=-64 bold=0 italic=0 charset="" unicode=1 stretchH=100 smooth=1 aa=1 padding=0,0,0,0 spacing=2,2 outline=2
|
||||
common lineHeight=81 base=59 scaleW=1024 scaleH=1024 pages=1 packed=0 alphaChnl=0 redChnl=4 greenChnl=4 blueChnl=4
|
||||
page id=0 file="symbola.png"
|
||||
chars count=187
|
||||
char id=9749 x=135 y=333 width=63 height=61 xoffset=1 yoffset=9 xadvance=65 page=0 chnl=15
|
||||
char id=9752 x=366 y=396 width=57 height=59 xoffset=0 yoffset=10 xadvance=58 page=0 chnl=15
|
||||
char id=9760 x=257 y=0 width=46 height=68 xoffset=0 yoffset=7 xadvance=47 page=0 chnl=15
|
||||
char id=9785 x=61 y=579 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=9786 x=183 y=578 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=10083 x=984 y=200 width=35 height=50 xoffset=1 yoffset=12 xadvance=37 page=0 chnl=15
|
||||
char id=10084 x=266 y=697 width=58 height=44 xoffset=1 yoffset=15 xadvance=60 page=0 chnl=15
|
||||
char id=127744 x=736 y=266 width=40 height=63 xoffset=4 yoffset=10 xadvance=48 page=0 chnl=15
|
||||
char id=127789 x=401 y=637 width=64 height=56 xoffset=0 yoffset=14 xadvance=64 page=0 chnl=15
|
||||
char id=127790 x=697 y=331 width=62 height=60 xoffset=1 yoffset=10 xadvance=64 page=0 chnl=15
|
||||
char id=127791 x=0 y=699 width=64 height=51 xoffset=0 yoffset=17 xadvance=64 page=0 chnl=15
|
||||
char id=127792 x=456 y=202 width=64 height=63 xoffset=0 yoffset=9 xadvance=64 page=0 chnl=15
|
||||
char id=127798 x=523 y=695 width=58 height=35 xoffset=3 yoffset=27 xadvance=64 page=0 chnl=15
|
||||
char id=127805 x=825 y=330 width=60 height=60 xoffset=0 yoffset=11 xadvance=60 page=0 chnl=15
|
||||
char id=127806 x=259 y=268 width=60 height=63 xoffset=0 yoffset=10 xadvance=60 page=0 chnl=15
|
||||
char id=127807 x=322 y=333 width=59 height=61 xoffset=0 yoffset=10 xadvance=60 page=0 chnl=15
|
||||
char id=127808 x=0 y=269 width=63 height=63 xoffset=0 yoffset=9 xadvance=63 page=0 chnl=15
|
||||
char id=127811 x=305 y=396 width=59 height=59 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=127812 x=696 y=0 width=64 height=66 xoffset=2 yoffset=8 xadvance=68 page=0 chnl=15
|
||||
char id=127813 x=61 y=397 width=58 height=60 xoffset=0 yoffset=11 xadvance=58 page=0 chnl=15
|
||||
char id=127814 x=946 y=265 width=61 height=62 xoffset=0 yoffset=9 xadvance=61 page=0 chnl=15
|
||||
char id=127815 x=584 y=635 width=56 height=56 xoffset=0 yoffset=12 xadvance=56 page=0 chnl=15
|
||||
char id=127827 x=121 y=397 width=58 height=60 xoffset=0 yoffset=10 xadvance=58 page=0 chnl=15
|
||||
char id=127828 x=0 y=334 width=68 height=61 xoffset=0 yoffset=10 xadvance=68 page=0 chnl=15
|
||||
char id=127829 x=68 y=70 width=65 height=65 xoffset=0 yoffset=8 xadvance=65 page=0 chnl=15
|
||||
char id=127830 x=737 y=135 width=59 height=64 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=127831 x=560 y=0 width=66 height=66 xoffset=0 yoffset=8 xadvance=66 page=0 chnl=15
|
||||
char id=127832 x=135 y=70 width=65 height=65 xoffset=0 yoffset=8 xadvance=65 page=0 chnl=15
|
||||
char id=127837 x=630 y=331 width=65 height=60 xoffset=0 yoffset=13 xadvance=65 page=0 chnl=15
|
||||
char id=127838 x=628 y=0 width=66 height=66 xoffset=0 yoffset=8 xadvance=66 page=0 chnl=15
|
||||
char id=127839 x=566 y=267 width=59 height=63 xoffset=0 yoffset=9 xadvance=59 page=0 chnl=15
|
||||
char id=127840 x=562 y=332 width=66 height=60 xoffset=0 yoffset=12 xadvance=66 page=0 chnl=15
|
||||
char id=127841 x=798 y=135 width=57 height=64 xoffset=0 yoffset=9 xadvance=57 page=0 chnl=15
|
||||
char id=127842 x=467 y=637 width=57 height=56 xoffset=0 yoffset=13 xadvance=57 page=0 chnl=15
|
||||
char id=127845 x=213 y=137 width=65 height=64 xoffset=0 yoffset=9 xadvance=65 page=0 chnl=15
|
||||
char id=127846 x=950 y=67 width=34 height=65 xoffset=0 yoffset=8 xadvance=34 page=0 chnl=15
|
||||
char id=127850 x=522 y=202 width=64 height=63 xoffset=0 yoffset=9 xadvance=64 page=0 chnl=15
|
||||
char id=127851 x=544 y=135 width=64 height=64 xoffset=0 yoffset=9 xadvance=65 page=0 chnl=15
|
||||
char id=127855 x=440 y=333 width=49 height=61 xoffset=0 yoffset=10 xadvance=49 page=0 chnl=15
|
||||
char id=127856 x=207 y=638 width=64 height=57 xoffset=0 yoffset=11 xadvance=64 page=0 chnl=15
|
||||
char id=127857 x=710 y=633 width=65 height=55 xoffset=0 yoffset=13 xadvance=66 page=0 chnl=15
|
||||
char id=127858 x=237 y=396 width=66 height=59 xoffset=0 yoffset=12 xadvance=66 page=0 chnl=15
|
||||
char id=127859 x=195 y=268 width=62 height=63 xoffset=1 yoffset=9 xadvance=64 page=0 chnl=15
|
||||
char id=127861 x=77 y=0 width=65 height=68 xoffset=0 yoffset=6 xadvance=65 page=0 chnl=15
|
||||
char id=127862 x=857 y=135 width=57 height=64 xoffset=0 yoffset=9 xadvance=58 page=0 chnl=15
|
||||
char id=127863 x=47 y=203 width=41 height=64 xoffset=0 yoffset=9 xadvance=41 page=0 chnl=15
|
||||
char id=127867 x=833 y=633 width=66 height=54 xoffset=0 yoffset=12 xadvance=66 page=0 chnl=15
|
||||
char id=127868 x=986 y=67 width=25 height=53 xoffset=0 yoffset=12 xadvance=25 page=0 chnl=15
|
||||
char id=127870 x=383 y=333 width=55 height=61 xoffset=1 yoffset=10 xadvance=57 page=0 chnl=15
|
||||
char id=127871 x=530 y=394 width=42 height=59 xoffset=0 yoffset=12 xadvance=42 page=0 chnl=15
|
||||
char id=127874 x=0 y=70 width=66 height=65 xoffset=0 yoffset=8 xadvance=66 page=0 chnl=15
|
||||
char id=128065 x=384 y=696 width=68 height=39 xoffset=-2 yoffset=19 xadvance=64 page=0 chnl=15
|
||||
char id=128068 x=132 y=698 width=57 height=47 xoffset=0 yoffset=15 xadvance=57 page=0 chnl=15
|
||||
char id=128069 x=777 y=633 width=54 height=55 xoffset=0 yoffset=14 xadvance=54 page=0 chnl=15
|
||||
char id=128121 x=478 y=136 width=64 height=64 xoffset=0 yoffset=8 xadvance=64 page=0 chnl=15
|
||||
char id=128122 x=65 y=269 width=63 height=63 xoffset=0 yoffset=9 xadvance=63 page=0 chnl=15
|
||||
char id=128123 x=339 y=637 width=60 height=57 xoffset=2 yoffset=14 xadvance=64 page=0 chnl=15
|
||||
char id=128125 x=505 y=267 width=59 height=63 xoffset=0 yoffset=9 xadvance=60 page=0 chnl=15
|
||||
char id=128126 x=321 y=268 width=60 height=63 xoffset=2 yoffset=7 xadvance=64 page=0 chnl=15
|
||||
char id=128127 x=889 y=67 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=128128 x=627 y=266 width=55 height=63 xoffset=0 yoffset=9 xadvance=55 page=0 chnl=15
|
||||
char id=128139 x=574 y=394 width=68 height=58 xoffset=0 yoffset=12 xadvance=68 page=0 chnl=15
|
||||
char id=128140 x=202 y=70 width=65 height=65 xoffset=0 yoffset=8 xadvance=65 page=0 chnl=15
|
||||
char id=128147 x=642 y=634 width=66 height=55 xoffset=0 yoffset=12 xadvance=66 page=0 chnl=15
|
||||
char id=128151 x=588 y=201 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15
|
||||
char id=128152 x=280 y=137 width=64 height=64 xoffset=0 yoffset=9 xadvance=64 page=0 chnl=15
|
||||
char id=128153 x=654 y=201 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15
|
||||
char id=128155 x=720 y=201 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15
|
||||
char id=128156 x=786 y=201 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15
|
||||
char id=128157 x=77 y=137 width=67 height=64 xoffset=0 yoffset=9 xadvance=68 page=0 chnl=15
|
||||
char id=128159 x=335 y=69 width=64 height=65 xoffset=0 yoffset=8 xadvance=64 page=0 chnl=15
|
||||
char id=128162 x=130 y=268 width=63 height=63 xoffset=0 yoffset=9 xadvance=63 page=0 chnl=15
|
||||
char id=128163 x=146 y=137 width=65 height=64 xoffset=0 yoffset=9 xadvance=65 page=0 chnl=15
|
||||
char id=128164 x=454 y=695 width=67 height=38 xoffset=0 yoffset=23 xadvance=67 page=0 chnl=15
|
||||
char id=128169 x=916 y=134 width=57 height=64 xoffset=0 yoffset=9 xadvance=58 page=0 chnl=15
|
||||
char id=128420 x=852 y=201 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15
|
||||
char id=128512 x=732 y=513 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128514 x=644 y=393 width=63 height=58 xoffset=0 yoffset=12 xadvance=63 page=0 chnl=15
|
||||
char id=128515 x=610 y=514 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128518 x=488 y=517 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128519 x=144 y=0 width=59 height=68 xoffset=0 yoffset=7 xadvance=59 page=0 chnl=15
|
||||
char id=128520 x=584 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=128521 x=427 y=517 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128523 x=61 y=519 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128524 x=0 y=519 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128525 x=915 y=452 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128526 x=854 y=452 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128527 x=793 y=453 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128528 x=732 y=453 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128529 x=671 y=453 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128530 x=488 y=457 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128533 x=122 y=459 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128534 x=854 y=572 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128535 x=305 y=457 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128536 x=122 y=579 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128537 x=366 y=517 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128538 x=244 y=577 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128539 x=305 y=577 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128541 x=366 y=577 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128542 x=427 y=577 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128543 x=488 y=577 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128544 x=549 y=575 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128545 x=671 y=573 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128546 x=732 y=573 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128547 x=793 y=573 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128548 x=427 y=0 width=59 height=67 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=128549 x=915 y=572 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128550 x=0 y=639 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128553 x=898 y=392 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128554 x=959 y=391 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128555 x=0 y=459 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128556 x=61 y=459 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128557 x=305 y=0 width=59 height=67 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=128558 x=183 y=458 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128559 x=244 y=457 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128560 x=709 y=393 width=61 height=58 xoffset=0 yoffset=12 xadvance=62 page=0 chnl=15
|
||||
char id=128561 x=835 y=392 width=61 height=58 xoffset=0 yoffset=12 xadvance=61 page=0 chnl=15
|
||||
char id=128562 x=366 y=457 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128563 x=427 y=457 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128564 x=90 y=203 width=88 height=63 xoffset=0 yoffset=7 xadvance=59 page=0 chnl=15
|
||||
char id=128565 x=549 y=455 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128566 x=610 y=574 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128567 x=610 y=454 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128568 x=401 y=69 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=128569 x=878 y=0 width=67 height=65 xoffset=0 yoffset=8 xadvance=67 page=0 chnl=15
|
||||
char id=128570 x=523 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=128571 x=828 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=128573 x=767 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=128575 x=706 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=128576 x=645 y=68 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=128577 x=122 y=519 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128578 x=183 y=518 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128579 x=244 y=517 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=128580 x=305 y=517 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129296 x=200 y=333 width=59 height=61 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129297 x=366 y=0 width=59 height=67 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=129298 x=383 y=268 width=59 height=63 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129299 x=549 y=515 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129300 x=0 y=0 width=75 height=68 xoffset=0 yoffset=7 xadvance=72 page=0 chnl=15
|
||||
char id=129301 x=671 y=513 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129302 x=181 y=396 width=54 height=60 xoffset=2 yoffset=7 xadvance=59 page=0 chnl=15
|
||||
char id=129303 x=778 y=266 width=98 height=62 xoffset=-1 yoffset=12 xadvance=96 page=0 chnl=15
|
||||
char id=129312 x=0 y=137 width=75 height=64 xoffset=-1 yoffset=9 xadvance=74 page=0 chnl=15
|
||||
char id=129314 x=793 y=513 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129315 x=346 y=136 width=64 height=64 xoffset=-1 yoffset=9 xadvance=64 page=0 chnl=15
|
||||
char id=129316 x=444 y=267 width=59 height=63 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129319 x=488 y=0 width=70 height=66 xoffset=0 yoffset=8 xadvance=70 page=0 chnl=15
|
||||
char id=129320 x=854 y=512 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129321 x=915 y=512 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129322 x=0 y=579 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129323 x=762 y=0 width=59 height=66 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=129324 x=772 y=393 width=61 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129325 x=949 y=329 width=59 height=60 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129326 x=261 y=333 width=59 height=61 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129327 x=462 y=69 width=59 height=65 xoffset=0 yoffset=8 xadvance=59 page=0 chnl=15
|
||||
char id=129346 x=975 y=134 width=46 height=64 xoffset=-1 yoffset=8 xadvance=44 page=0 chnl=15
|
||||
char id=129347 x=675 y=135 width=60 height=64 xoffset=-1 yoffset=9 xadvance=58 page=0 chnl=15
|
||||
char id=129360 x=70 y=334 width=63 height=61 xoffset=-1 yoffset=10 xadvance=61 page=0 chnl=15
|
||||
char id=129361 x=191 y=698 width=73 height=45 xoffset=-1 yoffset=18 xadvance=72 page=0 chnl=15
|
||||
char id=129362 x=253 y=203 width=66 height=63 xoffset=-1 yoffset=9 xadvance=64 page=0 chnl=15
|
||||
char id=129363 x=122 y=639 width=83 height=57 xoffset=-1 yoffset=14 xadvance=82 page=0 chnl=15
|
||||
char id=129364 x=491 y=332 width=69 height=60 xoffset=-1 yoffset=11 xadvance=68 page=0 chnl=15
|
||||
char id=129365 x=412 y=136 width=64 height=64 xoffset=-1 yoffset=8 xadvance=63 page=0 chnl=15
|
||||
char id=129366 x=947 y=0 width=66 height=65 xoffset=-1 yoffset=8 xadvance=65 page=0 chnl=15
|
||||
char id=129367 x=180 y=203 width=71 height=63 xoffset=-1 yoffset=8 xadvance=70 page=0 chnl=15
|
||||
char id=129368 x=878 y=266 width=66 height=62 xoffset=-1 yoffset=9 xadvance=65 page=0 chnl=15
|
||||
char id=129369 x=269 y=70 width=64 height=65 xoffset=-1 yoffset=8 xadvance=63 page=0 chnl=15
|
||||
char id=129370 x=823 y=0 width=53 height=66 xoffset=1 yoffset=8 xadvance=55 page=0 chnl=15
|
||||
char id=129371 x=205 y=0 width=50 height=68 xoffset=1 yoffset=7 xadvance=52 page=0 chnl=15
|
||||
char id=129372 x=389 y=202 width=65 height=63 xoffset=1 yoffset=9 xadvance=67 page=0 chnl=15
|
||||
char id=129373 x=887 y=330 width=60 height=60 xoffset=1 yoffset=10 xadvance=62 page=0 chnl=15
|
||||
char id=129374 x=961 y=632 width=61 height=51 xoffset=1 yoffset=15 xadvance=64 page=0 chnl=15
|
||||
char id=129375 x=526 y=637 width=56 height=56 xoffset=1 yoffset=12 xadvance=58 page=0 chnl=15
|
||||
char id=129377 x=425 y=396 width=53 height=59 xoffset=1 yoffset=10 xadvance=56 page=0 chnl=15
|
||||
char id=129378 x=321 y=203 width=66 height=63 xoffset=-1 yoffset=9 xadvance=64 page=0 chnl=15
|
||||
char id=129379 x=761 y=331 width=62 height=60 xoffset=1 yoffset=12 xadvance=64 page=0 chnl=15
|
||||
char id=129380 x=480 y=396 width=48 height=59 xoffset=4 yoffset=13 xadvance=56 page=0 chnl=15
|
||||
char id=129381 x=0 y=397 width=59 height=60 xoffset=0 yoffset=10 xadvance=59 page=0 chnl=15
|
||||
char id=129382 x=684 y=266 width=50 height=63 xoffset=1 yoffset=10 xadvance=53 page=0 chnl=15
|
||||
char id=129383 x=610 y=135 width=63 height=64 xoffset=1 yoffset=8 xadvance=65 page=0 chnl=15
|
||||
char id=129384 x=901 y=632 width=58 height=53 xoffset=2 yoffset=16 xadvance=63 page=0 chnl=15
|
||||
char id=129385 x=326 y=696 width=56 height=41 xoffset=2 yoffset=19 xadvance=60 page=0 chnl=15
|
||||
char id=129386 x=273 y=637 width=64 height=57 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15
|
||||
char id=129387 x=0 y=203 width=45 height=64 xoffset=4 yoffset=9 xadvance=53 page=0 chnl=15
|
||||
char id=129472 x=66 y=699 width=64 height=49 xoffset=0 yoffset=14 xadvance=64 page=0 chnl=15
|
||||
char id=129488 x=61 y=639 width=59 height=58 xoffset=0 yoffset=12 xadvance=59 page=0 chnl=15
|
||||
char id=129505 x=918 y=200 width=64 height=63 xoffset=0 yoffset=10 xadvance=64 page=0 chnl=15
|
||||
BIN
examples/text/resources/symbola.png
Normal file
|
After Width: | Height: | Size: 239 KiB |
586
examples/text/unicode.zig
Normal file
@ -0,0 +1,586 @@
|
||||
//!******************************************************************************************
|
||||
//!
|
||||
//! raylib-zig port of the [text] example - Unicode
|
||||
//! https://github.com/raysan5/raylib/blob/master/examples/text/text_unicode.c
|
||||
//!
|
||||
//! Example complexity rating: [★★★★] 4/4
|
||||
//!
|
||||
//! Example originally created with raylib 2.5, last time updated with raylib 4.0
|
||||
//!
|
||||
//! Example contributed by Vlad Adrian (@demizdor) and reviewed by Ramon Santamaria (@raysan5)
|
||||
//! Translated to raylib-zig by Timothy Fiss (@TheFissk)
|
||||
//!
|
||||
//! Example licensed under an unmodified zlib/libpng license, which is an OSI-certified,
|
||||
//! BSD-like license that allows static linking with closed source software
|
||||
//!
|
||||
//! Copyright (c) 2019-2025 Vlad Adrian (@demizdor) and Ramon Santamaria (@raysan5)
|
||||
//!
|
||||
//!*******************************************************************************************/
|
||||
|
||||
const rl = @import("raylib");
|
||||
const std = @import("std");
|
||||
|
||||
const emoji_per_width = 8;
|
||||
const emoji_per_height = 4;
|
||||
|
||||
// String containing 180 emoji codepoints separated by a '\0' char
|
||||
const emojiCodepoints = "\xF0\x9F\x8C\x80\x00\xF0\x9F\x98\x80\x00\xF0\x9F\x98\x82\x00\xF0\x9F\xA4\xA3\x00\xF0\x9F\x98\x83\x00\xF0\x9F\x98\x86\x00\xF0\x9F\x98\x89\x00" ++
|
||||
"\xF0\x9F\x98\x8B\x00\xF0\x9F\x98\x8E\x00\xF0\x9F\x98\x8D\x00\xF0\x9F\x98\x98\x00\xF0\x9F\x98\x97\x00\xF0\x9F\x98\x99\x00\xF0\x9F\x98\x9A\x00\xF0\x9F\x99\x82\x00" ++
|
||||
"\xF0\x9F\xA4\x97\x00\xF0\x9F\xA4\xA9\x00\xF0\x9F\xA4\x94\x00\xF0\x9F\xA4\xA8\x00\xF0\x9F\x98\x90\x00\xF0\x9F\x98\x91\x00\xF0\x9F\x98\xB6\x00\xF0\x9F\x99\x84\x00" ++
|
||||
"\xF0\x9F\x98\x8F\x00\xF0\x9F\x98\xA3\x00\xF0\x9F\x98\xA5\x00\xF0\x9F\x98\xAE\x00\xF0\x9F\xA4\x90\x00\xF0\x9F\x98\xAF\x00\xF0\x9F\x98\xAA\x00\xF0\x9F\x98\xAB\x00" ++
|
||||
"\xF0\x9F\x98\xB4\x00\xF0\x9F\x98\x8C\x00\xF0\x9F\x98\x9B\x00\xF0\x9F\x98\x9D\x00\xF0\x9F\xA4\xA4\x00\xF0\x9F\x98\x92\x00\xF0\x9F\x98\x95\x00\xF0\x9F\x99\x83\x00" ++
|
||||
"\xF0\x9F\xA4\x91\x00\xF0\x9F\x98\xB2\x00\xF0\x9F\x99\x81\x00\xF0\x9F\x98\x96\x00\xF0\x9F\x98\x9E\x00\xF0\x9F\x98\x9F\x00\xF0\x9F\x98\xA4\x00\xF0\x9F\x98\xA2\x00" ++
|
||||
"\xF0\x9F\x98\xAD\x00\xF0\x9F\x98\xA6\x00\xF0\x9F\x98\xA9\x00\xF0\x9F\xA4\xAF\x00\xF0\x9F\x98\xAC\x00\xF0\x9F\x98\xB0\x00\xF0\x9F\x98\xB1\x00\xF0\x9F\x98\xB3\x00" ++
|
||||
"\xF0\x9F\xA4\xAA\x00\xF0\x9F\x98\xB5\x00\xF0\x9F\x98\xA1\x00\xF0\x9F\x98\xA0\x00\xF0\x9F\xA4\xAC\x00\xF0\x9F\x98\xB7\x00\xF0\x9F\xA4\x92\x00\xF0\x9F\xA4\x95\x00" ++
|
||||
"\xF0\x9F\xA4\xA2\x00\xF0\x9F\xA4\xAE\x00\xF0\x9F\xA4\xA7\x00\xF0\x9F\x98\x87\x00\xF0\x9F\xA4\xA0\x00\xF0\x9F\xA4\xAB\x00\xF0\x9F\xA4\xAD\x00\xF0\x9F\xA7\x90\x00" ++
|
||||
"\xF0\x9F\xA4\x93\x00\xF0\x9F\x98\x88\x00\xF0\x9F\x91\xBF\x00\xF0\x9F\x91\xB9\x00\xF0\x9F\x91\xBA\x00\xF0\x9F\x92\x80\x00\xF0\x9F\x91\xBB\x00\xF0\x9F\x91\xBD\x00" ++
|
||||
"\xF0\x9F\x91\xBE\x00\xF0\x9F\xA4\x96\x00\xF0\x9F\x92\xA9\x00\xF0\x9F\x98\xBA\x00\xF0\x9F\x98\xB8\x00\xF0\x9F\x98\xB9\x00\xF0\x9F\x98\xBB\x00\xF0\x9F\x98\xBD\x00" ++
|
||||
"\xF0\x9F\x99\x80\x00\xF0\x9F\x98\xBF\x00\xF0\x9F\x8C\xBE\x00\xF0\x9F\x8C\xBF\x00\xF0\x9F\x8D\x80\x00\xF0\x9F\x8D\x83\x00\xF0\x9F\x8D\x87\x00\xF0\x9F\x8D\x93\x00" ++
|
||||
"\xF0\x9F\xA5\x9D\x00\xF0\x9F\x8D\x85\x00\xF0\x9F\xA5\xA5\x00\xF0\x9F\xA5\x91\x00\xF0\x9F\x8D\x86\x00\xF0\x9F\xA5\x94\x00\xF0\x9F\xA5\x95\x00\xF0\x9F\x8C\xBD\x00" ++
|
||||
"\xF0\x9F\x8C\xB6\x00\xF0\x9F\xA5\x92\x00\xF0\x9F\xA5\xA6\x00\xF0\x9F\x8D\x84\x00\xF0\x9F\xA5\x9C\x00\xF0\x9F\x8C\xB0\x00\xF0\x9F\x8D\x9E\x00\xF0\x9F\xA5\x90\x00" ++
|
||||
"\xF0\x9F\xA5\x96\x00\xF0\x9F\xA5\xA8\x00\xF0\x9F\xA5\x9E\x00\xF0\x9F\xA7\x80\x00\xF0\x9F\x8D\x96\x00\xF0\x9F\x8D\x97\x00\xF0\x9F\xA5\xA9\x00\xF0\x9F\xA5\x93\x00" ++
|
||||
"\xF0\x9F\x8D\x94\x00\xF0\x9F\x8D\x9F\x00\xF0\x9F\x8D\x95\x00\xF0\x9F\x8C\xAD\x00\xF0\x9F\xA5\xAA\x00\xF0\x9F\x8C\xAE\x00\xF0\x9F\x8C\xAF\x00\xF0\x9F\xA5\x99\x00" ++
|
||||
"\xF0\x9F\xA5\x9A\x00\xF0\x9F\x8D\xB3\x00\xF0\x9F\xA5\x98\x00\xF0\x9F\x8D\xB2\x00\xF0\x9F\xA5\xA3\x00\xF0\x9F\xA5\x97\x00\xF0\x9F\x8D\xBF\x00\xF0\x9F\xA5\xAB\x00" ++
|
||||
"\xF0\x9F\x8D\xB1\x00\xF0\x9F\x8D\x98\x00\xF0\x9F\x8D\x9D\x00\xF0\x9F\x8D\xA0\x00\xF0\x9F\x8D\xA2\x00\xF0\x9F\x8D\xA5\x00\xF0\x9F\x8D\xA1\x00\xF0\x9F\xA5\x9F\x00" ++
|
||||
"\xF0\x9F\xA5\xA1\x00\xF0\x9F\x8D\xA6\x00\xF0\x9F\x8D\xAA\x00\xF0\x9F\x8E\x82\x00\xF0\x9F\x8D\xB0\x00\xF0\x9F\xA5\xA7\x00\xF0\x9F\x8D\xAB\x00\xF0\x9F\x8D\xAF\x00" ++
|
||||
"\xF0\x9F\x8D\xBC\x00\xF0\x9F\xA5\x9B\x00\xF0\x9F\x8D\xB5\x00\xF0\x9F\x8D\xB6\x00\xF0\x9F\x8D\xBE\x00\xF0\x9F\x8D\xB7\x00\xF0\x9F\x8D\xBB\x00\xF0\x9F\xA5\x82\x00" ++
|
||||
"\xF0\x9F\xA5\x83\x00\xF0\x9F\xA5\xA4\x00\xF0\x9F\xA5\xA2\x00\xF0\x9F\x91\x81\x00\xF0\x9F\x91\x85\x00\xF0\x9F\x91\x84\x00\xF0\x9F\x92\x8B\x00\xF0\x9F\x92\x98\x00" ++
|
||||
"\xF0\x9F\x92\x93\x00\xF0\x9F\x92\x97\x00\xF0\x9F\x92\x99\x00\xF0\x9F\x92\x9B\x00\xF0\x9F\xA7\xA1\x00\xF0\x9F\x92\x9C\x00\xF0\x9F\x96\xA4\x00\xF0\x9F\x92\x9D\x00" ++
|
||||
"\xF0\x9F\x92\x9F\x00\xF0\x9F\x92\x8C\x00\xF0\x9F\x92\xA4\x00\xF0\x9F\x92\xA2\x00\xF0\x9F\x92\xA3\x00";
|
||||
|
||||
const Message = struct {
|
||||
text: [:0]const u8,
|
||||
language: [:0]const u8,
|
||||
};
|
||||
|
||||
/// Array containing all of the emojis messages
|
||||
const messages = [_]Message{
|
||||
.{
|
||||
.text = "\x46\x61\x6C\x73\x63\x68\x65\x73\x20\xC3\x9C\x62\x65\x6E\x20\x76\x6F\x6E\x20\x58\x79\x6C\x6F\x70\x68\x6F\x6E\x6D\x75\x73\x69\x6B\x20\x71\x75\xC3\xA4\x6C\x74\x20\x6A\x65\x64\x65\x6E\x20\x67\x72\xC3\xB6\xC3\x9F\x65\x72\x65\x6E\x20\x5A\x77\x65\x72\x67",
|
||||
.language = "German",
|
||||
},
|
||||
.{
|
||||
.text = "\x42\x65\x69\xC3\x9F\x20\x6E\x69\x63\x68\x74\x20\x69\x6E\x20\x64\x69\x65\x20\x48\x61\x6E\x64\x2C\x20\x64\x69\x65\x20\x64\x69\x63\x68\x20\x66\xC3\xBC\x74\x74\x65\x72\x74\x2E",
|
||||
.language = "German",
|
||||
},
|
||||
.{
|
||||
.text = "\x41\x75\xC3\x9F\x65\x72\x6F\x72\x64\x65\x6E\x74\x6C\x69\x63\x68\x65\x20\xC3\x9C\x62\x65\x6C\x20\x65\x72\x66\x6F\x72\x64\x65\x72\x6E\x20\x61\x75\xC3\x9F\x65\x72\x6F\x72\x64\x65\x6E\x74\x6C\x69\x63\x68\x65\x20\x4D\x69\x74\x74\x65\x6C\x2E",
|
||||
.language = "German",
|
||||
},
|
||||
.{
|
||||
.text = "\xD4\xBF\xD6\x80\xD5\xB6\xD5\xA1\xD5\xB4\x20\xD5\xA1\xD5\xBA\xD5\xA1\xD5\xAF\xD5\xAB\x20\xD5\xB8\xD6\x82\xD5\xBF\xD5\xA5\xD5\xAC\x20\xD6\x87\x20\xD5\xAB\xD5\xB6\xD5\xAE\xD5\xAB\x20\xD5\xA1\xD5\xB6\xD5\xB0\xD5\xA1\xD5\xB6\xD5\xA3\xD5\xAB\xD5\xBD\xD5\xBF\x20\xD5\xB9\xD5\xA8\xD5\xB6\xD5\xA5\xD6\x80",
|
||||
.language = "Armenian",
|
||||
},
|
||||
.{
|
||||
.text = "\xD4\xB5\xD6\x80\xD5\xA2\x20\xD5\xB8\xD6\x80\x20\xD5\xAF\xD5\xA1\xD6\x81\xD5\xAB\xD5\xB6\xD5\xA8\x20\xD5\xA5\xD5\xAF\xD5\xA1\xD6\x82\x20\xD5\xA1\xD5\xB6\xD5\xBF\xD5\xA1\xD5\xBC\x2C\x20\xD5\xAE\xD5\xA1\xD5\xBC\xD5\xA5\xD6\x80\xD5\xA8\x20\xD5\xA1\xD5\xBD\xD5\xA1\xD6\x81\xD5\xAB\xD5\xB6\x2E\x2E\x2E\x20\xC2\xAB\xD4\xBF\xD5\xB8\xD5\xBF\xD5\xA8\x20\xD5\xB4\xD5\xA5\xD6\x80\xD5\xB8\xD5\xB6\xD6\x81\xD5\xAB\xD6\x81\x20\xD5\xA7\x3A\xC2\xBB",
|
||||
.language = "Armenian",
|
||||
},
|
||||
.{
|
||||
.text = "\xD4\xB3\xD5\xA1\xD5\xBC\xD5\xA8\xD5\x9D\x20\xD5\xA3\xD5\xA1\xD6\x80\xD5\xB6\xD5\xA1\xD5\xB6\x2C\x20\xD5\xB1\xD5\xAB\xD6\x82\xD5\xB6\xD5\xA8\xD5\x9D\x20\xD5\xB1\xD5\xB4\xD5\xBC\xD5\xA1\xD5\xB6",
|
||||
.language = "Armenian",
|
||||
},
|
||||
.{
|
||||
.text = "\x4A\x65\xC5\xBC\x75\x20\x6B\x6C\xC4\x85\x74\x77\x2C\x20\x73\x70\xC5\x82\xC3\xB3\x64\xC5\xBA\x20\x46\x69\x6E\x6F\x6D\x20\x63\x7A\xC4\x99\xC5\x9B\xC4\x87\x20\x67\x72\x79\x20\x68\x61\xC5\x84\x62\x21",
|
||||
.language = "Polish",
|
||||
},
|
||||
.{
|
||||
.text = "\x44\x6F\x62\x72\x79\x6D\x69\x20\x63\x68\xC4\x99\x63\x69\x61\x6D\x69\x20\x6A\x65\x73\x74\x20\x70\x69\x65\x6B\xC5\x82\x6F\x20\x77\x79\x62\x72\x75\x6B\x6F\x77\x61\x6E\x65\x2E",
|
||||
.language = "Polish",
|
||||
},
|
||||
.{
|
||||
.text = "\xC3\x8E\xC8\x9B\x69\x20\x6D\x75\x6C\xC8\x9B\x75\x6D\x65\x73\x63\x20\x63\xC4\x83\x20\x61\x69\x20\x61\x6C\x65\x73\x20\x72\x61\x79\x6C\x69\x62\x2E\x0A\xC8\x98\x69\x20\x73\x70\x65\x72\x20\x73\xC4\x83\x20\x61\x69\x20\x6F\x20\x7A\x69\x20\x62\x75\x6E\xC4\x83\x21",
|
||||
.language = "Romanian",
|
||||
},
|
||||
.{
|
||||
.text = "\xD0\xAD\xD1\x85\x2C\x20\xD1\x87\xD1\x83\xD0\xB6\xD0\xB0\xD0\xBA\x2C\x20\xD0\xBE\xD0\xB1\xD1\x89\xD0\xB8\xD0\xB9\x20\xD1\x81\xD1\x8A\xD1\x91\xD0\xBC\x20\xD1\x86\xD0\xB5\xD0\xBD\x20\xD1\x88\xD0\xBB\xD1\x8F\xD0\xBF\x20\x28\xD1\x8E\xD1\x84\xD1\x82\xD1\x8C\x29\x20\xD0\xB2\xD0\xB4\xD1\x80\xD1\x8B\xD0\xB7\xD0\xB3\x21",
|
||||
.language = "Russian",
|
||||
},
|
||||
.{
|
||||
.text = "\xD0\xAF\x20\xD0\xBB\xD1\x8E\xD0\xB1\xD0\xBB\xD1\x8E\x20\x72\x61\x79\x6C\x69\x62\x21",
|
||||
.language = "Russian",
|
||||
},
|
||||
.{
|
||||
.text = "\xD0\x9C\xD0\xBE\xD0\xBB\xD1\x87\xD0\xB8\x2C\x20\xD1\x81\xD0\xBA\xD1\x80\xD1\x8B\xD0\xB2\xD0\xB0\xD0\xB9\xD1\x81\xD1\x8F\x20\xD0\xB8\x20\xD1\x82\xD0\xB0\xD0\xB8\x0A\xD0\x98\x20\xD1\x87\xD1\x83\xD0\xB2\xD1\x81\xD1\x82\xD0\xB2\xD0\xB0\x20\xD0\xB8\x20\xD0\xBC\xD0\xB5\xD1\x87\xD1\x82\xD1\x8B\x20\xD1\x81\xD0\xB2\xD0\xBE\xD0\xB8\x20\xE2\x80\x93\x0A\xD0\x9F\xD1\x83\xD1\x81\xD0\xBA\xD0\xB0\xD0\xB9\x20\xD0\xB2\x20\xD0\xB4\xD1\x83\xD1\x88\xD0\xB5\xD0\xB2\xD0\xBD\xD0\xBE\xD0\xB9\x20\xD0\xB3\xD0\xBB\xD1\x83\xD0\xB1\xD0\xB8\xD0\xBD\xD0\xB5\x0A\xD0\x98\x20\xD0\xB2\xD1\x81\xD1\x85\xD0\xBE\xD0\xB4\xD1\x8F\xD1\x82\x20\xD0\xB8\x20\xD0\xB7\xD0\xB0\xD0\xB9\xD0\xB4\xD1\x83\xD1\x82\x20\xD0\xBE\xD0\xBD\xD0\xB5\x0A\xD0\x9A\xD0\xB0\xD0\xBA\x20\xD0\xB7\xD0\xB2\xD0\xB5\xD0\xB7\xD0\xB4\xD1\x8B\x20\xD1\x8F\xD1\x81\xD0\xBD\xD1\x8B\xD0\xB5\x20\xD0\xB2\x20\xD0\xBD\xD0\xBE\xD1\x87\xD0\xB8\x2D\x0A\xD0\x9B\xD1\x8E\xD0\xB1\xD1\x83\xD0\xB9\xD1\x81\xD1\x8F\x20\xD0\xB8\xD0\xBC\xD0\xB8\x20\xE2\x80\x93\x20\xD0\xB8\x20\xD0\xBC\xD0\xBE\xD0\xBB\xD1\x87\xD0\xB8\x2E",
|
||||
.language = "Russian",
|
||||
},
|
||||
.{
|
||||
.text = "\x56\x6F\x69\x78\x20\x61\x6D\x62\x69\x67\x75\xC3\xAB\x20\x64\xE2\x80\x99\x75\x6E\x20\x63\xC5\x93\x75\x72\x20\x71\x75\x69\x20\x61\x75\x20\x7A\xC3\xA9\x70\x68\x79\x72\x20\x70\x72\xC3\xA9\x66\xC3\xA8\x72\x65\x20\x6C\x65\x73\x20\x6A\x61\x74\x74\x65\x73\x20\x64\x65\x20\x6B\x69\x77\x69",
|
||||
.language = "French",
|
||||
},
|
||||
.{
|
||||
.text = "\x42\x65\x6E\x6A\x61\x6D\xC3\xAD\x6E\x20\x70\x69\x64\x69\xC3\xB3\x20\x75\x6E\x61\x20\x62\x65\x62\x69\x64\x61\x20\x64\x65\x20\x6B\x69\x77\x69\x20\x79\x20\x66\x72\x65\x73\x61\x3B\x20\x4E\x6F\xC3\xA9\x2C\x20\x73\x69\x6E\x20\x76\x65\x72\x67\xC3\xBC\x65\x6E\x7A\x61\x2C\x20\x6C\x61\x20\x6D\xC3\xA1\x73\x20\x65\x78\x71\x75\x69\x73\x69\x74\x61\x20\x63\x68\x61\x6D\x70\x61\xC3\xB1\x61\x20\x64\x65\x6C\x20\x6D\x65\x6E\xC3\xBA\x2E",
|
||||
.language = "Spanish",
|
||||
},
|
||||
.{
|
||||
.text = "\xCE\xA4\xCE\xB1\xCF\x87\xCE\xAF\xCF\x83\xCF\x84\xCE\xB7\x20\xCE\xB1\xCE\xBB\xCF\x8E\xCF\x80\xCE\xB7\xCE\xBE\x20\xCE\xB2\xCE\xB1\xCF\x86\xCE\xAE\xCF\x82\x20\xCF\x88\xCE\xB7\xCE\xBC\xCE\xAD\xCE\xBD\xCE\xB7\x20\xCE\xB3\xCE\xB7\x2C\x20\xCE\xB4\xCF\x81\xCE\xB1\xCF\x83\xCE\xBA\xCE\xB5\xCE\xBB\xCE\xAF\xCE\xB6\xCE\xB5\xCE\xB9\x20\xCF\x85\xCF\x80\xCE\xAD\xCF\x81\x20\xCE\xBD\xCF\x89\xCE\xB8\xCF\x81\xCE\xBF\xCF\x8D\x20\xCE\xBA\xCF\x85\xCE\xBD\xCF\x8C\xCF\x82",
|
||||
.language = "Greek",
|
||||
},
|
||||
.{
|
||||
.text = "\xCE\x97\x20\xCE\xBA\xCE\xB1\xCE\xBB\xCF\x8D\xCF\x84\xCE\xB5\xCF\x81\xCE\xB7\x20\xCE\xAC\xCE\xBC\xCF\x85\xCE\xBD\xCE\xB1\x20\xCE\xB5\xCE\xAF\xCE\xBD\xCE\xB1\xCE\xB9\x20\xCE\xB7\x20\xCE\xB5\xCF\x80\xCE\xAF\xCE\xB8\xCE\xB5\xCF\x83\xCE\xB7\x2E",
|
||||
.language = "Greek",
|
||||
},
|
||||
.{
|
||||
.text = "\xCE\xA7\xCF\x81\xCF\x8C\xCE\xBD\xCE\xB9\xCE\xB1\x20\xCE\xBA\xCE\xB1\xCE\xB9\x20\xCE\xB6\xCE\xB1\xCE\xBC\xCE\xAC\xCE\xBD\xCE\xB9\xCE\xB1\x21",
|
||||
.language = "Greek",
|
||||
},
|
||||
.{
|
||||
.text = "\xCE\xA0\xCF\x8E\xCF\x82\x20\xCF\x84\xCE\xB1\x20\xCF\x80\xCE\xB1\xCF\x82\x20\xCF\x83\xCE\xAE\xCE\xBC\xCE\xB5\xCF\x81\xCE\xB1\x3B",
|
||||
.language = "Greek",
|
||||
},
|
||||
.{
|
||||
.text = "\xE6\x88\x91\xE8\x83\xBD\xE5\x90\x9E\xE4\xB8\x8B\xE7\x8E\xBB\xE7\x92\x83\xE8\x80\x8C\xE4\xB8\x8D\xE4\xBC\xA4\xE8\xBA\xAB\xE4\xBD\x93\xE3\x80\x82",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE4\xBD\xA0\xE5\x90\x83\xE4\xBA\x86\xE5\x90\x97\xEF\xBC\x9F",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE4\xB8\x8D\xE4\xBD\x9C\xE4\xB8\x8D\xE6\xAD\xBB\xE3\x80\x82",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE6\x9C\x80\xE8\xBF\x91\xE5\xA5\xBD\xE5\x90\x97\xEF\xBC\x9F",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE5\xA1\x9E\xE7\xBF\x81\xE5\xA4\xB1\xE9\xA9\xAC\xEF\xBC\x8C\xE7\x84\x89\xE7\x9F\xA5\xE9\x9D\x9E\xE7\xA6\x8F\xE3\x80\x82",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE5\x8D\x83\xE5\x86\x9B\xE6\x98\x93\xE5\xBE\x97\x2C\x20\xE4\xB8\x80\xE5\xB0\x86\xE9\x9A\xBE\xE6\xB1\x82",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE4\xB8\x87\xE4\xBA\x8B\xE5\xBC\x80\xE5\xA4\xB4\xE9\x9A\xBE\xE3\x80\x82",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE9\xA3\x8E\xE6\x97\xA0\xE5\xB8\xB8\xE9\xA1\xBA\xEF\xBC\x8C\xE5\x85\xB5\xE6\x97\xA0\xE5\xB8\xB8\xE8\x83\x9C\xE3\x80\x82",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE6\xB4\xBB\xE5\x88\xB0\xE8\x80\x81\xEF\xBC\x8C\xE5\xAD\xA6\xE5\x88\xB0\xE8\x80\x81\xE3\x80\x82",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE4\xB8\x80\xE8\xA8\x80\xE6\x97\xA2\xE5\x87\xBA\xEF\xBC\x8C\xE9\xA9\xB7\xE9\xA9\xAC\xE9\x9A\xBE\xE8\xBF\xBD\xE3\x80\x82",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE8\xB7\xAF\xE9\x81\xA5\xE7\x9F\xA5\xE9\xA9\xAC\xE5\x8A\x9B\xEF\xBC\x8C\xE6\x97\xA5\xE4\xB9\x85\xE8\xA7\x81\xE4\xBA\xBA\xE5\xBF\x83",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE6\x9C\x89\xE7\x90\x86\xE8\xB5\xB0\xE9\x81\x8D\xE5\xA4\xA9\xE4\xB8\x8B\xEF\xBC\x8C\xE6\x97\xA0\xE7\x90\x86\xE5\xAF\xB8\xE6\xAD\xA5\xE9\x9A\xBE\xE8\xA1\x8C\xE3\x80\x82",
|
||||
.language = "Chinese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE7\x8C\xBF\xE3\x82\x82\xE6\x9C\xA8\xE3\x81\x8B\xE3\x82\x89\xE8\x90\xBD\xE3\x81\xA1\xE3\x82\x8B",
|
||||
.language = "Japanese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE4\xBA\x80\xE3\x81\xAE\xE7\x94\xB2\xE3\x82\x88\xE3\x82\x8A\xE5\xB9\xB4\xE3\x81\xAE\xE5\x8A\x9F",
|
||||
.language = "Japanese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE3\x81\x86\xE3\x82\x89\xE3\x82\x84\xE3\x81\xBE\xE3\x81\x97\x20\x20\xE6\x80\x9D\xE3\x81\xB2\xE5\x88\x87\xE3\x82\x8B\xE6\x99\x82\x20\x20\xE7\x8C\xAB\xE3\x81\xAE\xE6\x81\x8B",
|
||||
.language = "Japanese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE8\x99\x8E\xE7\xA9\xB4\xE3\x81\xAB\xE5\x85\xA5\xE3\x82\x89\xE3\x81\x9A\xE3\x82\x93\xE3\x81\xB0\xE8\x99\x8E\xE5\xAD\x90\xE3\x82\x92\xE5\xBE\x97\xE3\x81\x9A\xE3\x80\x82",
|
||||
.language = "Japanese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE4\xBA\x8C\xE5\x85\x8E\xE3\x82\x92\xE8\xBF\xBD\xE3\x81\x86\xE8\x80\x85\xE3\x81\xAF\xE4\xB8\x80\xE5\x85\x8E\xE3\x82\x92\xE3\x82\x82\xE5\xBE\x97\xE3\x81\x9A\xE3\x80\x82",
|
||||
.language = "Japanese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE9\xA6\xAC\xE9\xB9\xBF\xE3\x81\xAF\xE6\xAD\xBB\xE3\x81\xAA\xE3\x81\xAA\xE3\x81\x8D\xE3\x82\x83\xE6\xB2\xBB\xE3\x82\x89\xE3\x81\xAA\xE3\x81\x84\xE3\x80\x82",
|
||||
.language = "Japanese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE6\x9E\xAF\xE9\x87\x8E\xE8\xB7\xAF\xE3\x81\xAB\xE3\x80\x80\xE5\xBD\xB1\xE3\x81\x8B\xE3\x81\x95\xE3\x81\xAA\xE3\x82\x8A\xE3\x81\xA6\xE3\x80\x80\xE3\x82\x8F\xE3\x81\x8B\xE3\x82\x8C\xE3\x81\x91\xE3\x82\x8A",
|
||||
.language = "Japanese",
|
||||
},
|
||||
.{
|
||||
.text = "\xE7\xB9\xB0\xE3\x82\x8A\xE8\xBF\x94\xE3\x81\x97\xE9\xBA\xA6\xE3\x81\xAE\xE7\x95\x9D\xE7\xB8\xAB\xE3\x81\xB5\xE8\x83\xA1\xE8\x9D\xB6\xE5\x93\x89",
|
||||
.language = "Japanese",
|
||||
},
|
||||
.{
|
||||
.text = "\xEC\x95\x84\xEB\x93\x9D\xED\x95\x9C\x20\xEB\xB0\x94\xEB\x8B\xA4\x20\xEC\x9C\x84\xEC\x97\x90\x20\xEA\xB0\x88\xEB\xA7\xA4\xEA\xB8\xB0\x20\xEB\x91\x90\xEC\x97\x87\x20\xEB\x82\xA0\xEC\x95\x84\x20\xEB\x8F\x88\xEB\x8B\xA4\x2E\x0A\xEB\x84\x88\xED\x9B\x8C\xEB\x84\x88\xED\x9B\x8C\x20\xEC\x8B\x9C\xEB\xA5\xBC\x20\xEC\x93\xB4\xEB\x8B\xA4\x2E\x20\xEB\xAA\xA8\xEB\xA5\xB4\xEB\x8A\x94\x20\xEB\x82\x98\xEB\x9D\xBC\x20\xEA\xB8\x80\xEC\x9E\x90\xEB\x8B\xA4\x2E\x0A\xEB\x84\x90\xEB\x94\xB0\xEB\x9E\x80\x20\xED\x95\x98\xEB\x8A\x98\x20\xEB\xB3\xB5\xED\x8C\x90\xEC\x97\x90\x20\xEB\x82\x98\xEB\x8F\x84\x20\xEA\xB0\x99\xEC\x9D\xB4\x20\xEC\x8B\x9C\xEB\xA5\xBC\x20\xEC\x93\xB4\xEB\x8B\xA4\x2E",
|
||||
.language = "Korean",
|
||||
},
|
||||
.{
|
||||
.text = "\xEC\xA0\x9C\x20\xEB\x88\x88\xEC\x97\x90\x20\xEC\x95\x88\xEA\xB2\xBD\xEC\x9D\xB4\xEB\x8B\xA4",
|
||||
.language = "Korean",
|
||||
},
|
||||
.{
|
||||
.text = "\xEA\xBF\xA9\x20\xEB\xA8\xB9\xEA\xB3\xA0\x20\xEC\x95\x8C\x20\xEB\xA8\xB9\xEB\x8A\x94\xEB\x8B\xA4",
|
||||
.language = "Korean",
|
||||
},
|
||||
.{
|
||||
.text = "\xEB\xA1\x9C\xEB\xA7\x88\xEB\x8A\x94\x20\xED\x95\x98\xEB\xA3\xA8\xEC\x95\x84\xEC\xB9\xA8\xEC\x97\x90\x20\xEC\x9D\xB4\xEB\xA3\xA8\xEC\x96\xB4\xEC\xA7\x84\x20\xEA\xB2\x83\xEC\x9D\xB4\x20\xEC\x95\x84\xEB\x8B\x88\xEB\x8B\xA4",
|
||||
.language = "Korean",
|
||||
},
|
||||
.{
|
||||
.text = "\xEA\xB3\xA0\xEC\x83\x9D\x20\xEB\x81\x9D\xEC\x97\x90\x20\xEB\x82\x99\xEC\x9D\xB4\x20\xEC\x98\xA8\xEB\x8B\xA4",
|
||||
.language = "Korean",
|
||||
},
|
||||
.{
|
||||
.text = "\xEA\xB0\x9C\xEC\xB2\x9C\xEC\x97\x90\xEC\x84\x9C\x20\xEC\x9A\xA9\x20\xEB\x82\x9C\xEB\x8B\xA4",
|
||||
.language = "Korean",
|
||||
},
|
||||
.{
|
||||
.text = "\xEC\x95\x88\xEB\x85\x95\xED\x95\x98\xEC\x84\xB8\xEC\x9A\x94\x3F",
|
||||
.language = "Korean",
|
||||
},
|
||||
.{
|
||||
.text = "\xEB\xA7\x8C\xEB\x82\x98\xEC\x84\x9C\x20\xEB\xB0\x98\xEA\xB0\x91\xEC\x8A\xB5\xEB\x8B\x88\xEB\x8B\xA4",
|
||||
.language = "Korean",
|
||||
},
|
||||
.{
|
||||
.text = "\xED\x95\x9C\xEA\xB5\xAD\xEB\xA7\x90\x20\xED\x95\x98\xEC\x8B\xA4\x20\xEC\xA4\x84\x20\xEC\x95\x84\xEC\x84\xB8\xEC\x9A\x94\x3F",
|
||||
.language = "Korean",
|
||||
},
|
||||
};
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Global variables
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Arrays that holds the random emojis
|
||||
const Emoji = struct {
|
||||
index: usize, // Index inside `emojiCodepoints`
|
||||
message: *const Message, // Message index
|
||||
color: rl.Color, // Emoji color
|
||||
};
|
||||
|
||||
var emojis: [emoji_per_height * emoji_per_width]Emoji = undefined;
|
||||
|
||||
var hovered: ?*Emoji = null;
|
||||
var selected_emoji: ?*Emoji = null;
|
||||
|
||||
//------------------------------------------------------------------------------------
|
||||
// Program main entry point
|
||||
//------------------------------------------------------------------------------------
|
||||
pub fn main() anyerror!void {
|
||||
// Initialization
|
||||
//--------------------------------------------------------------------------------------
|
||||
const screen_width = 800;
|
||||
const screen_height = 450;
|
||||
|
||||
rl.setConfigFlags(.{ .msaa_4x_hint = true, .vsync_hint = true });
|
||||
rl.initWindow(screen_width, screen_height, "raylib [text] example - unicode");
|
||||
defer rl.closeWindow();
|
||||
|
||||
// Load the font resources
|
||||
// NOTE: fontAsian is for asian languages,
|
||||
// fontEmoji is the emojis and fontDefault is used for everything else
|
||||
const font_default = try rl.loadFont("examples/text/resources/dejavu.fnt");
|
||||
defer rl.unloadFont(font_default);
|
||||
const font_asian = try rl.loadFont("examples/text/resources/noto_cjk.fnt");
|
||||
defer rl.unloadFont(font_asian);
|
||||
const font_emoji = try rl.loadFont("examples/text/resources/symbola.fnt");
|
||||
defer rl.unloadFont(font_emoji);
|
||||
|
||||
var hovered_pos = rl.Vector2{ .x = 0.0, .y = 0.0 };
|
||||
var selected_pos = rl.Vector2{ .x = 0.0, .y = 0.0 };
|
||||
|
||||
// Set a random set of emojis when starting up
|
||||
randomizeEmoji();
|
||||
|
||||
rl.setTargetFPS(60); // Set our game to run at 60 frames-per-second
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Main loop
|
||||
while (!rl.windowShouldClose()) // Detect window close button or ESC key
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
// Add a new set of emojis when SPACE is pressed
|
||||
if (rl.isKeyPressed(.space)) randomizeEmoji();
|
||||
|
||||
// Set the selected emoji
|
||||
if (rl.isMouseButtonPressed(.left) and (hovered != null) and (hovered != selected_emoji)) {
|
||||
selected_emoji = hovered;
|
||||
selected_pos = hovered_pos;
|
||||
}
|
||||
|
||||
const mouse = rl.getMousePosition();
|
||||
var position = rl.Vector2{ .x = 28.8, .y = 10.0 };
|
||||
hovered = null;
|
||||
//----------------------------------------------------------------------------------
|
||||
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
// Draw random emojis in the background
|
||||
//------------------------------------------------------------------------------
|
||||
for (&emojis, 0..) |*emoji, i| {
|
||||
const txt = emojiCodepoints[emoji.index..];
|
||||
const emoji_rect = rl.Rectangle{
|
||||
.x = position.x,
|
||||
.y = position.y,
|
||||
.height = @floatFromInt(font_emoji.baseSize),
|
||||
.width = @floatFromInt(font_emoji.baseSize),
|
||||
};
|
||||
|
||||
if (!rl.checkCollisionPointRec(mouse, emoji_rect)) {
|
||||
rl.drawTextEx(font_emoji, txt, position, @floatFromInt(font_emoji.baseSize), 1.0, if (selected_emoji == emoji) emoji.color else rl.fade(.light_gray, 0.4));
|
||||
} else {
|
||||
rl.drawTextEx(font_emoji, txt, position, @floatFromInt(font_emoji.baseSize), 1.0, emoji.color);
|
||||
hovered = emoji;
|
||||
hovered_pos = position;
|
||||
}
|
||||
|
||||
if ((i != 0) and (i % emoji_per_width == 0)) {
|
||||
position.y += @as(f32, @floatFromInt(font_emoji.baseSize)) + 24.25;
|
||||
position.x = 28.8;
|
||||
} else {
|
||||
position.x += @as(f32, @floatFromInt(font_emoji.baseSize)) + 28.8;
|
||||
}
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Draw the message when a emoji is selected
|
||||
//------------------------------------------------------------------------------
|
||||
if (selected_emoji) |selected| {
|
||||
const message = selected.message;
|
||||
const horizontal_padding = 20;
|
||||
const vertical_padding = 30;
|
||||
var font = &font_default;
|
||||
|
||||
// Set correct font for asian languages
|
||||
font = if (rl.textIsEqual(message.language, "Chinese") or
|
||||
rl.textIsEqual(message.language, "Korean") or
|
||||
rl.textIsEqual(message.language, "Japanese")) &font_asian else font;
|
||||
|
||||
// Calculate size for the message box (approximate the height and width)
|
||||
var sz = rl.measureTextEx(font.*, message.text, @floatFromInt(font.baseSize), 1.0);
|
||||
if (sz.x > 300) {
|
||||
sz.y *= sz.x / 300;
|
||||
sz.x = 300;
|
||||
} else if (sz.x < 160) {
|
||||
sz.x = 160;
|
||||
}
|
||||
|
||||
var msg_rect = rl.Rectangle{
|
||||
.x = selected_pos.x - 38.8,
|
||||
.y = selected_pos.y,
|
||||
.width = 2 * horizontal_padding + sz.x,
|
||||
.height = 2 * vertical_padding + sz.y,
|
||||
};
|
||||
msg_rect.y -= msg_rect.height;
|
||||
|
||||
// Coordinates for the chat bubble triangle
|
||||
var a = rl.Vector2{ .x = selected_pos.x, .y = msg_rect.y + msg_rect.height };
|
||||
var b = rl.Vector2{ .x = a.x + 8, .y = a.y + 10 };
|
||||
var c = rl.Vector2{ .x = a.x + 10, .y = a.y };
|
||||
|
||||
// Don't go outside the screen
|
||||
if (msg_rect.x < 10) msg_rect.x += 28;
|
||||
if (msg_rect.y < 10) {
|
||||
msg_rect.y = selected_pos.y + 84;
|
||||
a.y = msg_rect.y;
|
||||
c.y = a.y;
|
||||
b.y = a.y - 10;
|
||||
|
||||
// Swap values so we can actually render the triangle :(
|
||||
const tmp = a;
|
||||
a = b;
|
||||
b = tmp;
|
||||
}
|
||||
|
||||
if (msg_rect.x + msg_rect.width > screen_width) msg_rect.x -= (msg_rect.x + msg_rect.width) - screen_width + 10;
|
||||
|
||||
// Draw chat bubble
|
||||
rl.drawRectangleRec(msg_rect, selected.color);
|
||||
rl.drawTriangle(a, b, c, selected.color);
|
||||
|
||||
// Draw the main text message
|
||||
const text_rect = rl.Rectangle{
|
||||
.x = msg_rect.x + horizontal_padding / 2,
|
||||
.y = msg_rect.y + vertical_padding / 2,
|
||||
.width = msg_rect.width - horizontal_padding,
|
||||
.height = msg_rect.height,
|
||||
};
|
||||
drawTextBoxed(font.*, message.text, text_rect, @floatFromInt(font.baseSize), 1.0, true, .white);
|
||||
|
||||
// Draw the info text below the main message
|
||||
const size = message.text.len;
|
||||
const length = rl.getCodepointCount(message.text);
|
||||
const info = rl.textFormat("%s %u characters %i bytes", .{ message.language.ptr, length, size });
|
||||
sz = rl.measureTextEx(font_default, info, 10, 1.0);
|
||||
|
||||
rl.drawText(info, @intFromFloat(text_rect.x + text_rect.width - sz.x), @intFromFloat(msg_rect.y + msg_rect.height - sz.y - 2), 10, .ray_white);
|
||||
}
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Draw the info text
|
||||
rl.drawText("These emojis have something to tell you, click each to find out!", (screen_width - 650) / 2, screen_height - 40, 20, .gray);
|
||||
rl.drawText("Each emoji is a unicode character from a font, not a texture... Press [SPACEBAR] to refresh", (screen_width - 484) / 2, screen_height - 16, 10, .gray);
|
||||
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
}
|
||||
|
||||
// Fills the emoji array with random emoji (only those emojis present in fontEmoji)
|
||||
fn randomizeEmoji() void {
|
||||
hovered = null;
|
||||
selected_emoji = null;
|
||||
const start = rl.getRandomValue(45, 360);
|
||||
|
||||
for (&emojis, 0..) |*emoji, i| {
|
||||
// 0-179 emoji codepoints (from emoji char array) each 4bytes + null char
|
||||
emoji.index = @intCast(rl.getRandomValue(0, 179) * 5);
|
||||
|
||||
// Generate a random color for this emoji
|
||||
const hue: f32 = @floatFromInt(@rem(start * @as(i32, @intCast(i + 1)), 360));
|
||||
emoji.color = rl.fade(rl.colorFromHSV(hue, 0.6, 0.85), 0.8);
|
||||
|
||||
// Set a random message for this emoji
|
||||
emoji.message = &messages[@intCast(rl.getRandomValue(0, messages.len - 1))];
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------
|
||||
// Module functions definition
|
||||
//--------------------------------------------------------------------------------------
|
||||
|
||||
// Draw text using font inside rectangle limits
|
||||
fn drawTextBoxed(font: rl.Font, text: [:0]const u8, rec: rl.Rectangle, font_size: f32, spacing: f32, word_wrap: bool, tint: rl.Color) void {
|
||||
drawTextBoxedSelectable(font, text, rec, font_size, spacing, word_wrap, tint, 0, 0, .white, .white);
|
||||
}
|
||||
|
||||
// Draw text using font inside rectangle limits with support for text selection
|
||||
fn drawTextBoxedSelectable(font: rl.Font, text: [:0]const u8, rec: rl.Rectangle, font_size: f32, spacing: f32, word_wrap: bool, tint: rl.Color, select_box_start: i32, select_length: i32, select_tint: rl.Color, select_back_tint: rl.Color) void {
|
||||
var select_start = select_box_start;
|
||||
const length = rl.textLength(text); // Total length in bytes of the text, scanned by codepoints in loop
|
||||
|
||||
var text_offset_y: f32 = 0; // Offset between lines (on line break '\n')
|
||||
var text_offset_x: f32 = 0.0; // Offset X to next character to draw
|
||||
|
||||
const scale_factor = font_size / @as(f32, @floatFromInt(font.baseSize)); // Character rectangle scaling factor
|
||||
|
||||
// Word/character wrapping mechanism variables
|
||||
const MeasureState = enum(u8) { measure, draw };
|
||||
var state: MeasureState = if (word_wrap) .measure else .draw;
|
||||
|
||||
var start_line: i32 = -1; // Index where to begin drawing (where a line begins)
|
||||
var end_line: i32 = -1; // Index where to stop drawing (where a line ends)
|
||||
var last_char: i32 = -1; // Holds last value of the character position
|
||||
|
||||
var i: i32 = 0;
|
||||
var k: i32 = 0;
|
||||
while (i < length) : ({
|
||||
i += 1;
|
||||
k += 1;
|
||||
}) {
|
||||
// Get next codepoint from byte string and glyph index in font
|
||||
var codepoint_byte_count: i32 = 0;
|
||||
const codepoint = rl.getCodepoint(text[@intCast(i)..], &codepoint_byte_count);
|
||||
const index: usize = @intCast(rl.getGlyphIndex(font, codepoint));
|
||||
|
||||
// NOTE: Normally we exit the decoding sequence as soon as a bad byte is found (and return 0x3f)
|
||||
// but we need to draw all of the bad bytes using the '?' symbol moving one byte
|
||||
if (codepoint == 0x3f) codepoint_byte_count = 1;
|
||||
i += @intCast(codepoint_byte_count - 1);
|
||||
|
||||
var glyph_width: f32 = 0;
|
||||
if (codepoint != '\n') {
|
||||
glyph_width = if (font.glyphs[index].advanceX == 0) font.recs[index].width * scale_factor else @as(f32, @floatFromInt(font.glyphs[index].advanceX)) * scale_factor;
|
||||
|
||||
if (i + 1 < length) glyph_width = glyph_width + spacing;
|
||||
}
|
||||
// NOTE: When wordWrap is ON we first measure how much of the text we can draw before going outside of the rec container
|
||||
// We store this info in startLine and endLine, then we change states, draw the text between those two variables
|
||||
// and change states again and again recursively until the end of the text (or until we get outside of the container).
|
||||
// When wordWrap is OFF we don't need the measure state so we go to the drawing state immediately
|
||||
// and begin drawing on the next line before we can get outside the container.
|
||||
if (state == .measure) {
|
||||
// TODO: There are multiple types of spaces in UNICODE, maybe it's a good idea to add support for more
|
||||
// Ref: http://jkorpela.fi/chars/spaces.html
|
||||
if ((codepoint == ' ') or (codepoint == '\t') or (codepoint == '\n')) end_line = @intCast(i);
|
||||
|
||||
if ((text_offset_x + glyph_width) > rec.width) {
|
||||
end_line = if (end_line < 1) @intCast(i) else end_line;
|
||||
if (i == end_line) end_line -= codepoint_byte_count;
|
||||
if ((start_line + codepoint_byte_count) == end_line) end_line = @as(i32, @intCast(i)) - codepoint_byte_count;
|
||||
|
||||
state = if (state == .draw) .measure else .draw;
|
||||
} else if ((i + 1) == length) {
|
||||
end_line = @intCast(i);
|
||||
state = if (state == .draw) .measure else .draw;
|
||||
} else if (codepoint == '\n') {
|
||||
state = if (state == .draw) .measure else .draw;
|
||||
}
|
||||
|
||||
if (state == .draw) {
|
||||
text_offset_x = 0;
|
||||
i = @intCast(start_line);
|
||||
glyph_width = 0;
|
||||
|
||||
// Save character position when we switch states
|
||||
const tmp = last_char;
|
||||
last_char = k - 1;
|
||||
k = tmp;
|
||||
}
|
||||
} else {
|
||||
if (codepoint == '\n') {
|
||||
if (!word_wrap) {
|
||||
const bS: f32 = @floatFromInt(font.baseSize);
|
||||
text_offset_y += (bS + bS / 2) * scale_factor;
|
||||
text_offset_x = 0;
|
||||
}
|
||||
} else {
|
||||
if (!word_wrap and ((text_offset_x + glyph_width) > rec.width)) {
|
||||
const bS: f32 = @floatFromInt(font.baseSize);
|
||||
text_offset_y += (bS + bS / 2) * scale_factor;
|
||||
text_offset_x = 0;
|
||||
}
|
||||
|
||||
// When text overflows rectangle height limit, just stop drawing
|
||||
if ((text_offset_y + @as(f32, @floatFromInt(font.baseSize)) * scale_factor) > rec.height) break;
|
||||
|
||||
// Draw selection background
|
||||
var is_glyph_selected = false;
|
||||
if ((select_start >= 0) and (k >= select_start) and (k < (select_start + select_length))) {
|
||||
rl.drawRectangleRec(.{
|
||||
.x = rec.x + text_offset_x - 1,
|
||||
.y = rec.y + text_offset_y,
|
||||
.width = glyph_width,
|
||||
.height = @as(f32, @floatFromInt(font.baseSize)) * scale_factor,
|
||||
}, select_back_tint);
|
||||
is_glyph_selected = true;
|
||||
}
|
||||
|
||||
// Draw current character glyph
|
||||
if ((codepoint != ' ') and (codepoint != '\t')) {
|
||||
rl.drawTextCodepoint(font, codepoint, .{
|
||||
.x = rec.x + text_offset_x,
|
||||
.y = rec.y + text_offset_y,
|
||||
}, font_size, if (is_glyph_selected) select_tint else tint);
|
||||
}
|
||||
}
|
||||
|
||||
if (word_wrap and (i == end_line)) {
|
||||
const bS: f32 = @floatFromInt(font.baseSize);
|
||||
text_offset_y += (bS + bS / 2) * scale_factor;
|
||||
text_offset_x = 0;
|
||||
start_line = end_line;
|
||||
end_line = -1;
|
||||
glyph_width = 0;
|
||||
select_start += last_char - k;
|
||||
k = last_char;
|
||||
|
||||
state = if (state == .draw) .measure else .draw;
|
||||
}
|
||||
}
|
||||
|
||||
if ((text_offset_x != 0) or (codepoint != ' ')) text_offset_x += glyph_width; // avoid leading spaces
|
||||
}
|
||||
}
|
||||
@ -25,9 +25,9 @@ pub fn main() void {
|
||||
{
|
||||
// Update
|
||||
//----------------------------------------------------------------------------------
|
||||
framesCounter += if (rl.isKeyDown(rl.KeyboardKey.space)) 8 else 1;
|
||||
framesCounter += if (rl.isKeyDown(.space)) 8 else 1;
|
||||
|
||||
if (rl.isKeyPressed(rl.KeyboardKey.enter)) framesCounter = 0;
|
||||
if (rl.isKeyPressed(.enter)) framesCounter = 0;
|
||||
//----------------------------------------------------------------------------------
|
||||
// Draw
|
||||
//----------------------------------------------------------------------------------
|
||||
@ -17,7 +17,7 @@ pub fn main() anyerror!void {
|
||||
defer rl.closeWindow(); // Close window and OpenGL context
|
||||
|
||||
// NOTE: Textures MUST be loaded after Window initialization (OpenGL context is required)
|
||||
const scarfy: rl.Texture = try rl.Texture.init("resources/textures/scarfy.png"); // Texture loading
|
||||
const scarfy = try rl.Texture.init("resources/textures/scarfy.png"); // Texture loading
|
||||
defer rl.unloadTexture(scarfy); // Texture unloading
|
||||
|
||||
const position = rl.Vector2.init(350.0, 280.0);
|
||||
@ -70,37 +70,37 @@ pub fn main() anyerror!void {
|
||||
rl.beginDrawing();
|
||||
defer rl.endDrawing();
|
||||
|
||||
rl.clearBackground(rl.Color.ray_white);
|
||||
rl.clearBackground(.ray_white);
|
||||
|
||||
rl.drawTexture(scarfy, 15, 40, rl.Color.white);
|
||||
rl.drawRectangleLines(15, 40, scarfy.width, scarfy.height, rl.Color.lime);
|
||||
rl.drawTexture(scarfy, 15, 40, .white);
|
||||
rl.drawRectangleLines(15, 40, scarfy.width, scarfy.height, .lime);
|
||||
rl.drawRectangleLines(
|
||||
15 + @as(i32, @intFromFloat(frameRec.x)),
|
||||
40 + @as(i32, @intFromFloat(frameRec.y)),
|
||||
@as(i32, @intFromFloat(frameRec.width)),
|
||||
@as(i32, @intFromFloat(frameRec.height)),
|
||||
rl.Color.red,
|
||||
.red,
|
||||
);
|
||||
|
||||
rl.drawText("FRAME SPEED: ", 165, 210, 10, rl.Color.dark_gray);
|
||||
rl.drawText(rl.textFormat("%02i FPS", .{framesSpeed}), 575, 210, 10, rl.Color.dark_gray);
|
||||
rl.drawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, rl.Color.dark_gray);
|
||||
rl.drawText("FRAME SPEED: ", 165, 210, 10, .dark_gray);
|
||||
rl.drawText(rl.textFormat("%02i FPS", .{framesSpeed}), 575, 210, 10, .dark_gray);
|
||||
rl.drawText("PRESS RIGHT/LEFT KEYS to CHANGE SPEED!", 290, 240, 10, .dark_gray);
|
||||
|
||||
for ([_]u32{0} ** MAX_FRAME_SPEED, 0..) |_, i| {
|
||||
if (i < framesSpeed) {
|
||||
rl.drawRectangle(250 + 21 * @as(i32, @intCast(i)), 205, 20, 20, rl.Color.red);
|
||||
rl.drawRectangle(250 + 21 * @as(i32, @intCast(i)), 205, 20, 20, .red);
|
||||
}
|
||||
rl.drawRectangleLines(250 + 21 * @as(i32, @intCast(i)), 205, 20, 20, rl.Color.maroon);
|
||||
rl.drawRectangleLines(250 + 21 * @as(i32, @intCast(i)), 205, 20, 20, .maroon);
|
||||
}
|
||||
|
||||
scarfy.drawRec(frameRec, position, rl.Color.white); // Draw part of the texture
|
||||
scarfy.drawRec(frameRec, position, .white); // Draw part of the texture
|
||||
|
||||
rl.drawText(
|
||||
"(c) Scarfy sprite by Eiden Marsal",
|
||||
screenWidth - 200,
|
||||
screenHeight - 20,
|
||||
10,
|
||||
rl.Color.gray,
|
||||
.gray,
|
||||
);
|
||||
//----------------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
@ -59,49 +59,49 @@ pub fn main() anyerror!void {
|
||||
// NOTE: Texture is scaled twice its size
|
||||
rl.drawTextureEx(
|
||||
background,
|
||||
rl.Vector2.init(scrolling_back, 20.0),
|
||||
.init(scrolling_back, 20.0),
|
||||
0.0,
|
||||
2.0,
|
||||
rl.Color.white,
|
||||
.white,
|
||||
);
|
||||
rl.drawTextureEx(
|
||||
background,
|
||||
rl.Vector2.init(@as(f32, @floatFromInt(background.width * 2)) + scrolling_back, 20),
|
||||
.init(@as(f32, @floatFromInt(background.width * 2)) + scrolling_back, 20),
|
||||
0.0,
|
||||
2.0,
|
||||
rl.Color.white,
|
||||
.white,
|
||||
);
|
||||
|
||||
// Draw midground image twice
|
||||
rl.drawTextureEx(
|
||||
midground,
|
||||
rl.Vector2.init(scrolling_mid, 20.0),
|
||||
.init(scrolling_mid, 20.0),
|
||||
0.0,
|
||||
2.0,
|
||||
rl.Color.white,
|
||||
.white,
|
||||
);
|
||||
rl.drawTextureEx(
|
||||
midground,
|
||||
rl.Vector2.init(@as(f32, @floatFromInt(midground.width * 2)) + scrolling_mid, 20),
|
||||
.init(@as(f32, @floatFromInt(midground.width * 2)) + scrolling_mid, 20),
|
||||
0.0,
|
||||
2.0,
|
||||
rl.Color.white,
|
||||
.white,
|
||||
);
|
||||
|
||||
// Draw foreground image twice
|
||||
rl.drawTextureEx(
|
||||
foreground,
|
||||
rl.Vector2.init(scrolling_fore, 70.0),
|
||||
.init(scrolling_fore, 70.0),
|
||||
0.0,
|
||||
2.0,
|
||||
rl.Color.white,
|
||||
.white,
|
||||
);
|
||||
rl.drawTextureEx(
|
||||
foreground,
|
||||
rl.Vector2.init(@as(f32, @floatFromInt(foreground.width * 2)) + scrolling_fore, 70),
|
||||
.init(@as(f32, @floatFromInt(foreground.width * 2)) + scrolling_fore, 70),
|
||||
0.0,
|
||||
2.0,
|
||||
rl.Color.white,
|
||||
.white,
|
||||
);
|
||||
|
||||
rl.drawText(
|
||||
@ -109,14 +109,14 @@ pub fn main() anyerror!void {
|
||||
10,
|
||||
10,
|
||||
20,
|
||||
rl.Color.red,
|
||||
.red,
|
||||
);
|
||||
rl.drawText(
|
||||
"(c) Cyberpunk Street Environment by Luis Zuno (@ansimuz)",
|
||||
screen_width - 330,
|
||||
screen_height - 20,
|
||||
10,
|
||||
rl.Color.ray_white,
|
||||
.ray_white,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -23,17 +23,99 @@ ZIGGIFY = {
|
||||
"c_uint": "u32"
|
||||
}
|
||||
|
||||
IGNORE_TYPES = [
|
||||
"[*c]Color",
|
||||
"[*c]GlyphInfo",
|
||||
"[*c]c_int",
|
||||
"[*c]c_uint",
|
||||
"[*c][*c]u8",
|
||||
"[*c][*c]const u8",
|
||||
"[*c]Material",
|
||||
"[*c]ModelAnimation",
|
||||
"[*c]f32",
|
||||
IGNORE_C_TYPE = [
|
||||
"rlGetShaderLocsDefault",
|
||||
]
|
||||
|
||||
TRIVIAL_SIZE = [
|
||||
"LoadFileData",
|
||||
"CompressData",
|
||||
"DecompressData",
|
||||
"EncodeDataBase64",
|
||||
"DecodeDataBase64",
|
||||
"ExportImageToMemory",
|
||||
"LoadImagePalette",
|
||||
"LoadCodepoints",
|
||||
"TextSplit",
|
||||
#"LoadMaterials",
|
||||
"LoadModelAnimations",
|
||||
]
|
||||
|
||||
HAS_ERROR = TRIVIAL_SIZE
|
||||
|
||||
MANUAL = [
|
||||
"TextFormat",
|
||||
"TraceLog",
|
||||
"LoadShader",
|
||||
"LoadRandomSequence",
|
||||
"ExportDataAsCode",
|
||||
"SaveFileData",
|
||||
"LoadImage",
|
||||
"LoadImageRaw",
|
||||
"LoadImageAnim",
|
||||
"LoadImageFromTexture",
|
||||
"LoadImageFromScreen",
|
||||
"LoadImageFromMemory",
|
||||
"LoadImageColors",
|
||||
"LoadMaterialDefault",
|
||||
"LoadMaterials", # todo: Make this automatic, by adding a IsXValid check in this script
|
||||
"LoadModel",
|
||||
"LoadModelFromMesh",
|
||||
"LoadTexture",
|
||||
"LoadTextureFromImage",
|
||||
"LoadTextureCubemap",
|
||||
"LoadRenderTexture",
|
||||
"LoadWave",
|
||||
"LoadWaveSamples",
|
||||
"LoadSound",
|
||||
"LoadMusicStream",
|
||||
"LoadAudioStream",
|
||||
"DrawMeshInstanced",
|
||||
"UnloadModelAnimations",
|
||||
"ComputeCRC32",
|
||||
"ComputeMD5",
|
||||
"ComputeSHA1",
|
||||
"SetWindowIcons",
|
||||
"CheckCollisionPointPoly",
|
||||
"ColorToInt",
|
||||
"GetFontDefault",
|
||||
"LoadFont",
|
||||
"LoadFontEx",
|
||||
"LoadFontFromImage",
|
||||
"LoadFontData",
|
||||
"ImageText",
|
||||
"ImageTextEx",
|
||||
"GenImageFontAtlas",
|
||||
"UnloadFontData",
|
||||
"DrawTextCodepoints",
|
||||
"LoadUTF8",
|
||||
"LoadTextLines",
|
||||
"UnloadTextLines",
|
||||
"TextJoin",
|
||||
"DrawLineStrip",
|
||||
"DrawTriangleFan",
|
||||
"DrawTriangleStrip",
|
||||
"DrawTriangleStrip3D",
|
||||
"GuiTabBar",
|
||||
"GuiListViewEx",
|
||||
"GuiPanel",
|
||||
"GuiScrollPanel",
|
||||
"GuiButton",
|
||||
"GuiLabelButton",
|
||||
"GuiCheckBox",
|
||||
"GuiTextBox",
|
||||
"DrawSplineLinear",
|
||||
"DrawSplineBasis",
|
||||
"DrawSplineCatmullRom",
|
||||
"DrawSplineBezierQuadratic",
|
||||
"DrawSplineBezierCubic",
|
||||
"ImageKernelConvolution",
|
||||
"GuiGetIcons",
|
||||
"GuiLoadIcons",
|
||||
"GuiSetStyle",
|
||||
"GuiGetStyle"
|
||||
]
|
||||
|
||||
# Some C types have a different sizes on different systems and Zig
|
||||
# knows that so we tell it to get the system specific size for us.
|
||||
def c_to_zig_type(c: str) -> str:
|
||||
@ -47,7 +129,9 @@ def c_to_zig_type(c: str) -> str:
|
||||
return const + c
|
||||
|
||||
|
||||
def ziggify_type(name: str, t: str, func_name) -> str:
|
||||
def ziggify_type(name: str, t: str, func_name: str) -> str:
|
||||
if func_name in IGNORE_C_TYPE:
|
||||
return t
|
||||
NO_STRINGS = ["data", "fileData", "compData"]
|
||||
|
||||
single = [
|
||||
@ -59,24 +143,24 @@ def ziggify_type(name: str, t: str, func_name) -> str:
|
||||
"AutomationEventList", "list", "batch", "glInternalFormat", "glFormat",
|
||||
"glType", "mipmaps", "active", "scroll", "view", "checked", "mouseCell",
|
||||
"scrollIndex", "focus", "secretViewActive", "color", "alpha", "colorHsv",
|
||||
"translation", "rotation", "scale", "mat"
|
||||
"translation", "rotation", "scale", "mat", "glyphCount"
|
||||
]
|
||||
multi = [
|
||||
"data", "compData", "points", "fileData", "colors", "pixels",
|
||||
"fontChars", "chars", "recs", "codepoints", "textList", "transforms",
|
||||
"animations", "samples", "LoadImageColors", "LoadImagePalette",
|
||||
"LoadFontData", "LoadCodepoints", "TextSplit", "LoadMaterials",
|
||||
"LoadFontData", "LoadCodepoints", "LoadMaterials",
|
||||
"LoadModelAnimations", "LoadWaveSamples", "images",
|
||||
"LoadRandomSequence", "sequence", "kernel", "GlyphInfo", "glyphs", "glyphRecs",
|
||||
"matf", "rlGetShaderLocsDefault", "locs", "GuiGetIcons", "GuiLoadIcons"
|
||||
]
|
||||
string = False
|
||||
|
||||
if name == "text" and t == "[*c][*c]const u8":
|
||||
if name == "text" and (t == "[*c][*c]const u8" or t == "[*c][*c]u8"):
|
||||
return "[][:0]const u8"
|
||||
|
||||
if t.startswith("[*c]") and name not in single and name not in multi:
|
||||
if (t == "[*c]const u8" or t == "[*c]u8") and name not in NO_STRINGS: # Strings are multis.
|
||||
if (t == "[*c]const u8" or t == "[*c]u8" or name == "TextSplit") and name not in NO_STRINGS: # Strings are multis.
|
||||
string = True
|
||||
else:
|
||||
raise ValueError(f"{t} {name} not classified")
|
||||
@ -84,7 +168,9 @@ def ziggify_type(name: str, t: str, func_name) -> str:
|
||||
pre = ""
|
||||
while t.startswith("[*c]"):
|
||||
t = t[4:]
|
||||
if string and not t.startswith("[*c]"):
|
||||
if func_name in TRIVIAL_SIZE and not pre:
|
||||
pre += "[]"
|
||||
elif string and not t.startswith("[*c]"):
|
||||
pre += "[:0]"
|
||||
elif name in single:
|
||||
pre += "*"
|
||||
@ -94,7 +180,11 @@ def ziggify_type(name: str, t: str, func_name) -> str:
|
||||
if t in ZIGGIFY:
|
||||
t = ZIGGIFY[t]
|
||||
|
||||
return pre + t
|
||||
error = ""
|
||||
if name in HAS_ERROR:
|
||||
error = "RaylibError!"
|
||||
|
||||
return error + pre + t
|
||||
|
||||
|
||||
def add_namespace_to_type(t: str) -> str:
|
||||
@ -108,7 +198,8 @@ def add_namespace_to_type(t: str) -> str:
|
||||
pre += "const "
|
||||
|
||||
if t.startswith("Gui"):
|
||||
t = "rgui." + t
|
||||
# Strip "Gui" prefix to match types in prelude
|
||||
t = "rgui." + t[3:]
|
||||
elif t[0].isupper():
|
||||
t = "rl." + t
|
||||
elif t in ["float3", "float16"]:
|
||||
@ -119,21 +210,20 @@ def add_namespace_to_type(t: str) -> str:
|
||||
return pre + t
|
||||
|
||||
|
||||
def make_return_cast(source_type: str, dest_type: str, inner: str) -> str:
|
||||
if source_type == dest_type:
|
||||
def make_return_cast(func_name: str, source_type: str, dest_type: str, inner: str) -> str:
|
||||
if source_type == dest_type or func_name in IGNORE_C_TYPE:
|
||||
return inner
|
||||
if source_type.startswith("[*c][*c]"):
|
||||
inner = f"@as([*][:0]{source_type[8:]}, @ptrCast({inner}))"
|
||||
if func_name in TRIVIAL_SIZE:
|
||||
return f"{inner}[0..@as(usize, @intCast(_len))]"
|
||||
if source_type in ["[*c]const u8", "[*c]u8"]:
|
||||
return f"std.mem.span({inner})"
|
||||
|
||||
if source_type in ZIGGIFY:
|
||||
return f"@as({dest_type}, {inner})"
|
||||
|
||||
# These all have to be done manually because their sizes depend on the
|
||||
# function arguments.
|
||||
if source_type in IGNORE_TYPES:
|
||||
return None
|
||||
else:
|
||||
raise ValueError(f"Don't know what to do {source_type} {dest_type} {inner}")
|
||||
raise ValueError(f"Don't know what to do with '{func_name}': {source_type} {dest_type} {inner}")
|
||||
|
||||
|
||||
def fix_pointer(name: str, t: str):
|
||||
@ -175,8 +265,8 @@ _fix_enums_data = [
|
||||
("button", "GamepadButton", r".*GamepadButton.*"),
|
||||
("axis", "GamepadAxis", r".*GamepadAxis.*"),
|
||||
("button", "MouseButton", r".*MouseButton.*"),
|
||||
("control", "GuiControl", r"Gui.etStyle"),
|
||||
# ("property", "GuiControlProperty", r"Gui.etStyle"),
|
||||
("control", "GuiControl", r"Gui.etStyle"), # "Gui" prefix needed here for type parsing later
|
||||
# ("property", "GuiControlProperty", r"Gui.etStyle"), # "Gui" prefix needed here for type parsing later
|
||||
]
|
||||
def fix_enums(arg_name, arg_type, func_name):
|
||||
if func_name.startswith("rl"):
|
||||
@ -191,8 +281,12 @@ def fix_enums(arg_name, arg_type, func_name):
|
||||
return arg_type
|
||||
|
||||
|
||||
def convert_name_case(name):
|
||||
return name[:1].lower() + name[1:] if name else ''
|
||||
def convert_name(name):
|
||||
if not name:
|
||||
return ''
|
||||
if name.startswith("Gui"):
|
||||
name = name[3:]
|
||||
return name[:1].lower() + name[1:]
|
||||
|
||||
|
||||
def parse_header(header_name: str, output_file: str, ext_file: str, prefix: str, prelude_file: str, ext_prelude_file: str, skip_after: str = "#/never\\#"):
|
||||
@ -272,6 +366,8 @@ def parse_header(header_name: str, output_file: str, ext_file: str, prefix: str,
|
||||
if not arguments:
|
||||
arguments = "void"
|
||||
|
||||
zig_name = convert_name(func_name)
|
||||
|
||||
for arg in arguments.split(", "):
|
||||
if arg == "void":
|
||||
break
|
||||
@ -290,6 +386,9 @@ def parse_header(header_name: str, output_file: str, ext_file: str, prefix: str,
|
||||
arg_type = c_to_zig_type(arg_type)
|
||||
arg_name, arg_type = fix_pointer(arg_name, arg_type)
|
||||
|
||||
if arg_name == zig_name:
|
||||
arg_name += "_"
|
||||
|
||||
single_opt = [
|
||||
("rlDrawVertexArrayElements", "buffer"),
|
||||
("rlDrawVertexArrayElementsInstanced", "buffer"),
|
||||
@ -300,6 +399,7 @@ def parse_header(header_name: str, output_file: str, ext_file: str, prefix: str,
|
||||
("rlLoadShaderBuffer", "data"),
|
||||
("rlLoadShaderCode", "vsCode"),
|
||||
("rlLoadShaderCode", "fsCode"),
|
||||
("GuiTextInputBox", "secretViewActive")
|
||||
]
|
||||
|
||||
zig_type = ziggify_type(arg_name, arg_type, func_name)
|
||||
@ -324,89 +424,34 @@ def parse_header(header_name: str, output_file: str, ext_file: str, prefix: str,
|
||||
ext_ret = add_namespace_to_type(return_type)
|
||||
ext_heads.append(f"pub extern \"c\" fn {func_name}({zig_c_arguments}) {ext_ret};")
|
||||
|
||||
zig_name = convert_name_case(func_name)
|
||||
func_prelude = ""
|
||||
|
||||
if func_name in TRIVIAL_SIZE:
|
||||
zig_arguments.pop()
|
||||
zig_call_args[-1] = "@as([*c]c_int, @ptrCast(&_len))"
|
||||
func_prelude = "var _len: i32 = 0;\n "
|
||||
|
||||
# TODO: Ziggify return type
|
||||
zig_arguments = ", ".join(zig_arguments)
|
||||
zig_call_args = ", ".join(zig_call_args)
|
||||
|
||||
manual = [
|
||||
"TextFormat",
|
||||
"TraceLog",
|
||||
"LoadShader",
|
||||
"ExportDataAsCode",
|
||||
"LoadFileData",
|
||||
"SaveFileData",
|
||||
"LoadImage",
|
||||
"LoadImageRaw",
|
||||
"LoadImageAnim",
|
||||
"LoadImageFromTexture",
|
||||
"LoadImageFromScreen",
|
||||
"LoadImageFromMemory",
|
||||
"LoadMaterialDefault",
|
||||
"LoadMaterials",
|
||||
"LoadModel",
|
||||
"LoadModelFromMesh",
|
||||
"LoadTexture",
|
||||
"LoadTextureFromImage",
|
||||
"LoadTextureCubemap",
|
||||
"LoadRenderTexture",
|
||||
"LoadWave",
|
||||
"LoadSound",
|
||||
"LoadMusicStream",
|
||||
"LoadAudioStream",
|
||||
"DrawMeshInstanced",
|
||||
"UnloadModelAnimations",
|
||||
"CompressData",
|
||||
"DecompressData",
|
||||
"EncodeDataBase64",
|
||||
"DecodeDataBase64",
|
||||
"ComputeCRC32",
|
||||
"ComputeMD5",
|
||||
"ComputeSHA1",
|
||||
"SetWindowIcons",
|
||||
"CheckCollisionPointPoly",
|
||||
"ColorToInt",
|
||||
"GetFontDefault",
|
||||
"LoadFont",
|
||||
"LoadFontEx",
|
||||
"LoadFontFromImage",
|
||||
"ImageText",
|
||||
"ImageTextEx",
|
||||
"GenImageFontAtlas",
|
||||
"UnloadFontData",
|
||||
"DrawTextCodepoints",
|
||||
"LoadUTF8",
|
||||
"TextJoin",
|
||||
"DrawLineStrip",
|
||||
"DrawTriangleFan",
|
||||
"DrawTriangleStrip",
|
||||
"DrawTriangleStrip3D",
|
||||
"GuiTabBar",
|
||||
"GuiListViewEx",
|
||||
"GuiPanel",
|
||||
"GuiScrollPanel",
|
||||
"DrawSplineLinear",
|
||||
"DrawSplineBasis",
|
||||
"DrawSplineCatmullRom",
|
||||
"DrawSplineBezierQuadratic",
|
||||
"DrawSplineBezierCubic",
|
||||
"ImageKernelConvolution",
|
||||
"GuiSetStyle",
|
||||
"GuiGetStyle"
|
||||
]
|
||||
|
||||
if func_name in manual or "FromMemory" in func_name:
|
||||
if func_name in MANUAL or "FromMemory" in func_name:
|
||||
continue
|
||||
|
||||
inner = f"cdef.{func_name}({zig_call_args})"
|
||||
|
||||
if func_name in TRIVIAL_SIZE:
|
||||
func_prelude += f"const _ptr = {inner};\n if (_ptr == 0) return RaylibError.{func_name};\n "
|
||||
inner = "_ptr"
|
||||
|
||||
zig_return = ziggify_type(func_name, return_type, func_name)
|
||||
return_cast = make_return_cast(return_type, zig_return, f"cdef.{func_name}({zig_call_args})")
|
||||
return_cast = make_return_cast(func_name, return_type, zig_return, inner)
|
||||
|
||||
if return_cast:
|
||||
zig_funcs.append(
|
||||
inline_comment +
|
||||
f"pub fn {zig_name}({zig_arguments}) {zig_return}" +
|
||||
" {\n " +
|
||||
func_prelude +
|
||||
("return " if zig_return != "void" else "") +
|
||||
return_cast + ";"
|
||||
"\n}"
|
||||
|
||||
@ -15,38 +15,38 @@ const Color = rl.Color;
|
||||
const Rectangle = rl.Rectangle;
|
||||
const Font = rl.Font;
|
||||
|
||||
pub const GuiStyleProp = extern struct {
|
||||
pub const StyleProp = extern struct {
|
||||
controlId: c_ushort,
|
||||
propertyId: c_ushort,
|
||||
propertyValue: c_int,
|
||||
};
|
||||
|
||||
pub const GuiState = enum(c_int) {
|
||||
state_normal = 0,
|
||||
state_focused,
|
||||
state_pressed,
|
||||
state_disabled,
|
||||
pub const State = enum(c_int) {
|
||||
normal = 0,
|
||||
focused,
|
||||
pressed,
|
||||
disabled,
|
||||
};
|
||||
|
||||
pub const GuiTextAlignment = enum(c_int) {
|
||||
text_align_left = 0,
|
||||
text_align_center,
|
||||
text_align_right,
|
||||
pub const TextAlignment = enum(c_int) {
|
||||
left = 0,
|
||||
center,
|
||||
right,
|
||||
};
|
||||
|
||||
pub const GuiTextAlignmentVertical = enum(c_int) {
|
||||
text_align_top = 0,
|
||||
text_align_middle,
|
||||
text_align_bottom,
|
||||
pub const TextAlignmentVertical = enum(c_int) {
|
||||
top = 0,
|
||||
middle,
|
||||
bottom,
|
||||
};
|
||||
|
||||
pub const GuiTextWrapMode = enum(c_int) {
|
||||
text_wrap_none = 0,
|
||||
text_wrap_char,
|
||||
text_wrap_word,
|
||||
pub const TextWrapMode = enum(c_int) {
|
||||
none = 0,
|
||||
char,
|
||||
word,
|
||||
};
|
||||
|
||||
pub const GuiControl = enum(c_int) {
|
||||
pub const Control = enum(c_int) {
|
||||
default = 0,
|
||||
label,
|
||||
button,
|
||||
@ -58,14 +58,14 @@ pub const GuiControl = enum(c_int) {
|
||||
dropdownbox,
|
||||
textbox,
|
||||
valuebox,
|
||||
spinner,
|
||||
control11,
|
||||
listview,
|
||||
colorpicker,
|
||||
scrollbar,
|
||||
statusbar,
|
||||
};
|
||||
|
||||
pub const GuiControlProperty = enum(c_int) {
|
||||
pub const ControlProperty = enum(c_int) {
|
||||
border_color_normal = 0,
|
||||
base_color_normal,
|
||||
text_color_normal,
|
||||
@ -83,7 +83,7 @@ pub const GuiControlProperty = enum(c_int) {
|
||||
text_alignment,
|
||||
};
|
||||
|
||||
pub const GuiDefaultProperty = enum(c_int) {
|
||||
pub const DefaultProperty = enum(c_int) {
|
||||
text_size = 16,
|
||||
text_spacing,
|
||||
line_color,
|
||||
@ -93,20 +93,25 @@ pub const GuiDefaultProperty = enum(c_int) {
|
||||
text_wrap_mode,
|
||||
};
|
||||
|
||||
pub const GuiToggleProperty = enum(c_int) {
|
||||
pub const ControlOrDefaultProperty = union(enum) {
|
||||
control: ControlProperty,
|
||||
default: DefaultProperty,
|
||||
};
|
||||
|
||||
pub const ToggleProperty = enum(c_int) {
|
||||
group_padding = 16,
|
||||
};
|
||||
|
||||
pub const GuiSliderProperty = enum(c_int) {
|
||||
pub const SliderProperty = enum(c_int) {
|
||||
slider_width = 16,
|
||||
slider_padding,
|
||||
};
|
||||
|
||||
pub const GuiProgressBarProperty = enum(c_int) {
|
||||
pub const ProgressBarProperty = enum(c_int) {
|
||||
progress_padding = 16,
|
||||
};
|
||||
|
||||
pub const GuiScrollBarProperty = enum(c_int) {
|
||||
pub const ScrollBarProperty = enum(c_int) {
|
||||
arrows_size = 16,
|
||||
arrows_visible,
|
||||
scroll_slider_padding,
|
||||
@ -115,40 +120,41 @@ pub const GuiScrollBarProperty = enum(c_int) {
|
||||
scroll_speed,
|
||||
};
|
||||
|
||||
pub const GuiCheckBoxProperty = enum(c_int) {
|
||||
pub const CheckBoxProperty = enum(c_int) {
|
||||
check_padding = 16,
|
||||
};
|
||||
|
||||
pub const GuiComboBoxProperty = enum(c_int) {
|
||||
pub const ComboBoxProperty = enum(c_int) {
|
||||
combo_button_width = 16,
|
||||
combo_button_spacing,
|
||||
};
|
||||
|
||||
pub const GuiDropdownBoxProperty = enum(c_int) {
|
||||
pub const DropdownBoxProperty = enum(c_int) {
|
||||
arrow_padding = 16,
|
||||
dropdown_items_spacing,
|
||||
dropdown_arrow_hidden,
|
||||
dropdown_roll_up,
|
||||
};
|
||||
|
||||
pub const GuiTextBoxProperty = enum(c_int) {
|
||||
pub const TextBoxProperty = enum(c_int) {
|
||||
text_readonly = 16,
|
||||
};
|
||||
|
||||
pub const GuiSpinnerProperty = enum(c_int) {
|
||||
pub const ValueBoxProperty = enum(c_int) {
|
||||
spin_button_width = 16,
|
||||
spin_button_spacing,
|
||||
};
|
||||
|
||||
pub const GuiListViewProperty = enum(c_int) {
|
||||
pub const ListViewProperty = enum(c_int) {
|
||||
list_items_height = 16,
|
||||
list_items_spacing,
|
||||
scrollbar_width,
|
||||
scrollbar_side,
|
||||
list_items_border_normal,
|
||||
list_items_border_width,
|
||||
};
|
||||
|
||||
pub const GuiColorPickerProperty = enum(c_int) {
|
||||
pub const ColorPickerProperty = enum(c_int) {
|
||||
color_selector_size = 16,
|
||||
huebar_width,
|
||||
huebar_padding,
|
||||
@ -159,241 +165,241 @@ pub const GuiColorPickerProperty = enum(c_int) {
|
||||
pub const scrollbar_left_side: c_int = 0;
|
||||
pub const scrollbar_right_side: c_int = 1;
|
||||
|
||||
pub const GuiIconName = enum(c_int) {
|
||||
icon_none = 0,
|
||||
icon_folder_file_open = 1,
|
||||
icon_file_save_classic = 2,
|
||||
icon_folder_open = 3,
|
||||
icon_folder_save = 4,
|
||||
icon_file_open = 5,
|
||||
icon_file_save = 6,
|
||||
icon_file_export = 7,
|
||||
icon_file_add = 8,
|
||||
icon_file_delete = 9,
|
||||
icon_filetype_text = 10,
|
||||
icon_filetype_audio = 11,
|
||||
icon_filetype_image = 12,
|
||||
icon_filetype_play = 13,
|
||||
icon_filetype_video = 14,
|
||||
icon_filetype_info = 15,
|
||||
icon_file_copy = 16,
|
||||
icon_file_cut = 17,
|
||||
icon_file_paste = 18,
|
||||
icon_cursor_hand = 19,
|
||||
icon_cursor_pointer = 20,
|
||||
icon_cursor_classic = 21,
|
||||
icon_pencil = 22,
|
||||
icon_pencil_big = 23,
|
||||
icon_brush_classic = 24,
|
||||
icon_brush_painter = 25,
|
||||
icon_water_drop = 26,
|
||||
icon_color_picker = 27,
|
||||
icon_rubber = 28,
|
||||
icon_color_bucket = 29,
|
||||
icon_text_t = 30,
|
||||
icon_text_a = 31,
|
||||
icon_scale = 32,
|
||||
icon_resize = 33,
|
||||
icon_filter_point = 34,
|
||||
icon_filter_bilinear = 35,
|
||||
icon_crop = 36,
|
||||
icon_crop_alpha = 37,
|
||||
icon_square_toggle = 38,
|
||||
icon_symmetry = 39,
|
||||
icon_symmetry_horizontal = 40,
|
||||
icon_symmetry_vertical = 41,
|
||||
icon_lens = 42,
|
||||
icon_lens_big = 43,
|
||||
icon_eye_on = 44,
|
||||
icon_eye_off = 45,
|
||||
icon_filter_top = 46,
|
||||
icon_filter = 47,
|
||||
icon_target_point = 48,
|
||||
icon_target_small = 49,
|
||||
icon_target_big = 50,
|
||||
icon_target_move = 51,
|
||||
icon_cursor_move = 52,
|
||||
icon_cursor_scale = 53,
|
||||
icon_cursor_scale_right = 54,
|
||||
icon_cursor_scale_left = 55,
|
||||
icon_undo = 56,
|
||||
icon_redo = 57,
|
||||
icon_reredo = 58,
|
||||
icon_mutate = 59,
|
||||
icon_rotate = 60,
|
||||
icon_repeat = 61,
|
||||
icon_shuffle = 62,
|
||||
icon_emptybox = 63,
|
||||
icon_target = 64,
|
||||
icon_target_small_fill = 65,
|
||||
icon_target_big_fill = 66,
|
||||
icon_target_move_fill = 67,
|
||||
icon_cursor_move_fill = 68,
|
||||
icon_cursor_scale_fill = 69,
|
||||
icon_cursor_scale_right_fill = 70,
|
||||
icon_cursor_scale_left_fill = 71,
|
||||
icon_undo_fill = 72,
|
||||
icon_redo_fill = 73,
|
||||
icon_reredo_fill = 74,
|
||||
icon_mutate_fill = 75,
|
||||
icon_rotate_fill = 76,
|
||||
icon_repeat_fill = 77,
|
||||
icon_shuffle_fill = 78,
|
||||
icon_emptybox_small = 79,
|
||||
icon_box = 80,
|
||||
icon_box_top = 81,
|
||||
icon_box_top_right = 82,
|
||||
icon_box_right = 83,
|
||||
icon_box_bottom_right = 84,
|
||||
icon_box_bottom = 85,
|
||||
icon_box_bottom_left = 86,
|
||||
icon_box_left = 87,
|
||||
icon_box_top_left = 88,
|
||||
icon_box_center = 89,
|
||||
icon_box_circle_mask = 90,
|
||||
icon_pot = 91,
|
||||
icon_alpha_multiply = 92,
|
||||
icon_alpha_clear = 93,
|
||||
icon_dithering = 94,
|
||||
icon_mipmaps = 95,
|
||||
icon_box_grid = 96,
|
||||
icon_grid = 97,
|
||||
icon_box_corners_small = 98,
|
||||
icon_box_corners_big = 99,
|
||||
icon_four_boxes = 100,
|
||||
icon_grid_fill = 101,
|
||||
icon_box_multisize = 102,
|
||||
icon_zoom_small = 103,
|
||||
icon_zoom_medium = 104,
|
||||
icon_zoom_big = 105,
|
||||
icon_zoom_all = 106,
|
||||
icon_zoom_center = 107,
|
||||
icon_box_dots_small = 108,
|
||||
icon_box_dots_big = 109,
|
||||
icon_box_concentric = 110,
|
||||
icon_box_grid_big = 111,
|
||||
icon_ok_tick = 112,
|
||||
icon_cross = 113,
|
||||
icon_arrow_left = 114,
|
||||
icon_arrow_right = 115,
|
||||
icon_arrow_down = 116,
|
||||
icon_arrow_up = 117,
|
||||
icon_arrow_left_fill = 118,
|
||||
icon_arrow_right_fill = 119,
|
||||
icon_arrow_down_fill = 120,
|
||||
icon_arrow_up_fill = 121,
|
||||
icon_audio = 122,
|
||||
icon_fx = 123,
|
||||
icon_wave = 124,
|
||||
icon_wave_sinus = 125,
|
||||
icon_wave_square = 126,
|
||||
icon_wave_triangular = 127,
|
||||
icon_cross_small = 128,
|
||||
icon_player_previous = 129,
|
||||
icon_player_play_back = 130,
|
||||
icon_player_play = 131,
|
||||
icon_player_pause = 132,
|
||||
icon_player_stop = 133,
|
||||
icon_player_next = 134,
|
||||
icon_player_record = 135,
|
||||
icon_magnet = 136,
|
||||
icon_lock_close = 137,
|
||||
icon_lock_open = 138,
|
||||
icon_clock = 139,
|
||||
icon_tools = 140,
|
||||
icon_gear = 141,
|
||||
icon_gear_big = 142,
|
||||
icon_bin = 143,
|
||||
icon_hand_pointer = 144,
|
||||
icon_laser = 145,
|
||||
icon_coin = 146,
|
||||
icon_explosion = 147,
|
||||
icon_1up = 148,
|
||||
icon_player = 149,
|
||||
icon_player_jump = 150,
|
||||
icon_key = 151,
|
||||
icon_demon = 152,
|
||||
icon_text_popup = 153,
|
||||
icon_gear_ex = 154,
|
||||
icon_crack = 155,
|
||||
icon_crack_points = 156,
|
||||
icon_star = 157,
|
||||
icon_door = 158,
|
||||
icon_exit = 159,
|
||||
icon_mode_2d = 160,
|
||||
icon_mode_3d = 161,
|
||||
icon_cube = 162,
|
||||
icon_cube_face_top = 163,
|
||||
icon_cube_face_left = 164,
|
||||
icon_cube_face_front = 165,
|
||||
icon_cube_face_bottom = 166,
|
||||
icon_cube_face_right = 167,
|
||||
icon_cube_face_back = 168,
|
||||
icon_camera = 169,
|
||||
icon_special = 170,
|
||||
icon_link_net = 171,
|
||||
icon_link_boxes = 172,
|
||||
icon_link_multi = 173,
|
||||
icon_link = 174,
|
||||
icon_link_broke = 175,
|
||||
icon_text_notes = 176,
|
||||
icon_notebook = 177,
|
||||
icon_suitcase = 178,
|
||||
icon_suitcase_zip = 179,
|
||||
icon_mailbox = 180,
|
||||
icon_monitor = 181,
|
||||
icon_printer = 182,
|
||||
icon_photo_camera = 183,
|
||||
icon_photo_camera_flash = 184,
|
||||
icon_house = 185,
|
||||
icon_heart = 186,
|
||||
icon_corner = 187,
|
||||
icon_vertical_bars = 188,
|
||||
icon_vertical_bars_fill = 189,
|
||||
icon_life_bars = 190,
|
||||
icon_info = 191,
|
||||
icon_crossline = 192,
|
||||
icon_help = 193,
|
||||
icon_filetype_alpha = 194,
|
||||
icon_filetype_home = 195,
|
||||
icon_layers_visible = 196,
|
||||
icon_layers = 197,
|
||||
icon_window = 198,
|
||||
icon_hidpi = 199,
|
||||
icon_filetype_binary = 200,
|
||||
icon_hex = 201,
|
||||
icon_shield = 202,
|
||||
icon_file_new = 203,
|
||||
icon_folder_add = 204,
|
||||
icon_alarm = 205,
|
||||
icon_cpu = 206,
|
||||
icon_rom = 207,
|
||||
icon_step_over = 208,
|
||||
icon_step_into = 209,
|
||||
icon_step_out = 210,
|
||||
icon_restart = 211,
|
||||
icon_breakpoint_on = 212,
|
||||
icon_breakpoint_off = 213,
|
||||
icon_burger_menu = 214,
|
||||
icon_case_sensitive = 215,
|
||||
icon_reg_exp = 216,
|
||||
icon_folder = 217,
|
||||
icon_file = 218,
|
||||
icon_sand_timer = 219,
|
||||
icon_warning = 220,
|
||||
icon_help_box = 221,
|
||||
icon_info_box = 222,
|
||||
icon_223 = 223,
|
||||
icon_224 = 224,
|
||||
icon_225 = 225,
|
||||
icon_226 = 226,
|
||||
icon_227 = 227,
|
||||
icon_228 = 228,
|
||||
icon_229 = 229,
|
||||
icon_230 = 230,
|
||||
icon_231 = 231,
|
||||
icon_232 = 232,
|
||||
icon_233 = 233,
|
||||
pub const IconName = enum(c_int) {
|
||||
none = 0,
|
||||
folder_file_open = 1,
|
||||
file_save_classic = 2,
|
||||
folder_open = 3,
|
||||
folder_save = 4,
|
||||
file_open = 5,
|
||||
file_save = 6,
|
||||
file_export = 7,
|
||||
file_add = 8,
|
||||
file_delete = 9,
|
||||
filetype_text = 10,
|
||||
filetype_audio = 11,
|
||||
filetype_image = 12,
|
||||
filetype_play = 13,
|
||||
filetype_video = 14,
|
||||
filetype_info = 15,
|
||||
file_copy = 16,
|
||||
file_cut = 17,
|
||||
file_paste = 18,
|
||||
cursor_hand = 19,
|
||||
cursor_pointer = 20,
|
||||
cursor_classic = 21,
|
||||
pencil = 22,
|
||||
pencil_big = 23,
|
||||
brush_classic = 24,
|
||||
brush_painter = 25,
|
||||
water_drop = 26,
|
||||
color_picker = 27,
|
||||
rubber = 28,
|
||||
color_bucket = 29,
|
||||
text_t = 30,
|
||||
text_a = 31,
|
||||
scale = 32,
|
||||
resize = 33,
|
||||
filter_point = 34,
|
||||
filter_bilinear = 35,
|
||||
crop = 36,
|
||||
crop_alpha = 37,
|
||||
square_toggle = 38,
|
||||
symmetry = 39,
|
||||
symmetry_horizontal = 40,
|
||||
symmetry_vertical = 41,
|
||||
lens = 42,
|
||||
lens_big = 43,
|
||||
eye_on = 44,
|
||||
eye_off = 45,
|
||||
filter_top = 46,
|
||||
filter = 47,
|
||||
target_point = 48,
|
||||
target_small = 49,
|
||||
target_big = 50,
|
||||
target_move = 51,
|
||||
cursor_move = 52,
|
||||
cursor_scale = 53,
|
||||
cursor_scale_right = 54,
|
||||
cursor_scale_left = 55,
|
||||
undo = 56,
|
||||
redo = 57,
|
||||
reredo = 58,
|
||||
mutate = 59,
|
||||
rotate = 60,
|
||||
repeat = 61,
|
||||
shuffle = 62,
|
||||
emptybox = 63,
|
||||
target = 64,
|
||||
target_small_fill = 65,
|
||||
target_big_fill = 66,
|
||||
target_move_fill = 67,
|
||||
cursor_move_fill = 68,
|
||||
cursor_scale_fill = 69,
|
||||
cursor_scale_right_fill = 70,
|
||||
cursor_scale_left_fill = 71,
|
||||
undo_fill = 72,
|
||||
redo_fill = 73,
|
||||
reredo_fill = 74,
|
||||
mutate_fill = 75,
|
||||
rotate_fill = 76,
|
||||
repeat_fill = 77,
|
||||
shuffle_fill = 78,
|
||||
emptybox_small = 79,
|
||||
box = 80,
|
||||
box_top = 81,
|
||||
box_top_right = 82,
|
||||
box_right = 83,
|
||||
box_bottom_right = 84,
|
||||
box_bottom = 85,
|
||||
box_bottom_left = 86,
|
||||
box_left = 87,
|
||||
box_top_left = 88,
|
||||
box_center = 89,
|
||||
box_circle_mask = 90,
|
||||
pot = 91,
|
||||
alpha_multiply = 92,
|
||||
alpha_clear = 93,
|
||||
dithering = 94,
|
||||
mipmaps = 95,
|
||||
box_grid = 96,
|
||||
grid = 97,
|
||||
box_corners_small = 98,
|
||||
box_corners_big = 99,
|
||||
four_boxes = 100,
|
||||
grid_fill = 101,
|
||||
box_multisize = 102,
|
||||
zoom_small = 103,
|
||||
zoom_medium = 104,
|
||||
zoom_big = 105,
|
||||
zoom_all = 106,
|
||||
zoom_center = 107,
|
||||
box_dots_small = 108,
|
||||
box_dots_big = 109,
|
||||
box_concentric = 110,
|
||||
box_grid_big = 111,
|
||||
ok_tick = 112,
|
||||
cross = 113,
|
||||
arrow_left = 114,
|
||||
arrow_right = 115,
|
||||
arrow_down = 116,
|
||||
arrow_up = 117,
|
||||
arrow_left_fill = 118,
|
||||
arrow_right_fill = 119,
|
||||
arrow_down_fill = 120,
|
||||
arrow_up_fill = 121,
|
||||
audio = 122,
|
||||
fx = 123,
|
||||
wave = 124,
|
||||
wave_sinus = 125,
|
||||
wave_square = 126,
|
||||
wave_triangular = 127,
|
||||
cross_small = 128,
|
||||
player_previous = 129,
|
||||
player_play_back = 130,
|
||||
player_play = 131,
|
||||
player_pause = 132,
|
||||
player_stop = 133,
|
||||
player_next = 134,
|
||||
player_record = 135,
|
||||
magnet = 136,
|
||||
lock_close = 137,
|
||||
lock_open = 138,
|
||||
clock = 139,
|
||||
tools = 140,
|
||||
gear = 141,
|
||||
gear_big = 142,
|
||||
bin = 143,
|
||||
hand_pointer = 144,
|
||||
laser = 145,
|
||||
coin = 146,
|
||||
explosion = 147,
|
||||
@"1up" = 148,
|
||||
player = 149,
|
||||
player_jump = 150,
|
||||
key = 151,
|
||||
demon = 152,
|
||||
text_popup = 153,
|
||||
gear_ex = 154,
|
||||
crack = 155,
|
||||
crack_points = 156,
|
||||
star = 157,
|
||||
door = 158,
|
||||
exit = 159,
|
||||
mode_2d = 160,
|
||||
mode_3d = 161,
|
||||
cube = 162,
|
||||
cube_face_top = 163,
|
||||
cube_face_left = 164,
|
||||
cube_face_front = 165,
|
||||
cube_face_bottom = 166,
|
||||
cube_face_right = 167,
|
||||
cube_face_back = 168,
|
||||
camera = 169,
|
||||
special = 170,
|
||||
link_net = 171,
|
||||
link_boxes = 172,
|
||||
link_multi = 173,
|
||||
link = 174,
|
||||
link_broke = 175,
|
||||
text_notes = 176,
|
||||
notebook = 177,
|
||||
suitcase = 178,
|
||||
suitcase_zip = 179,
|
||||
mailbox = 180,
|
||||
monitor = 181,
|
||||
printer = 182,
|
||||
photo_camera = 183,
|
||||
photo_camera_flash = 184,
|
||||
house = 185,
|
||||
heart = 186,
|
||||
corner = 187,
|
||||
vertical_bars = 188,
|
||||
vertical_bars_fill = 189,
|
||||
life_bars = 190,
|
||||
info = 191,
|
||||
crossline = 192,
|
||||
help = 193,
|
||||
filetype_alpha = 194,
|
||||
filetype_home = 195,
|
||||
layers_visible = 196,
|
||||
layers = 197,
|
||||
window = 198,
|
||||
hidpi = 199,
|
||||
filetype_binary = 200,
|
||||
hex = 201,
|
||||
shield = 202,
|
||||
file_new = 203,
|
||||
folder_add = 204,
|
||||
alarm = 205,
|
||||
cpu = 206,
|
||||
rom = 207,
|
||||
step_over = 208,
|
||||
step_into = 209,
|
||||
step_out = 210,
|
||||
restart = 211,
|
||||
breakpoint_on = 212,
|
||||
breakpoint_off = 213,
|
||||
burger_menu = 214,
|
||||
case_sensitive = 215,
|
||||
reg_exp = 216,
|
||||
folder = 217,
|
||||
file = 218,
|
||||
sand_timer = 219,
|
||||
warning = 220,
|
||||
help_box = 221,
|
||||
info_box = 222,
|
||||
priority = 223,
|
||||
layers_iso = 224,
|
||||
layers2 = 225,
|
||||
mlayers = 226,
|
||||
maps = 227,
|
||||
hot = 228,
|
||||
label = 229,
|
||||
name_id = 230,
|
||||
slicing = 231,
|
||||
manual_control = 232,
|
||||
collision = 233,
|
||||
icon_234 = 234,
|
||||
icon_235 = 235,
|
||||
icon_236 = 236,
|
||||
@ -419,41 +425,25 @@ pub const GuiIconName = enum(c_int) {
|
||||
};
|
||||
|
||||
/// Set one style property
|
||||
pub fn guiSetStyle(control: GuiControl, comptime property: anytype, value: i32) void {
|
||||
comptime var property_int: c_int = undefined;
|
||||
|
||||
comptime {
|
||||
if (@TypeOf(property) == GuiControlProperty) {
|
||||
property_int = @intCast(@intFromEnum(property));
|
||||
} else if (@TypeOf(property) == GuiDefaultProperty) { // comparison can't be chained :(
|
||||
property_int = @intCast(@intFromEnum(property));
|
||||
} else {
|
||||
@compileError("Invalid property type for guiSetStyle");
|
||||
}
|
||||
}
|
||||
pub fn setStyle(control: Control, comptime property: ControlOrDefaultProperty, value: i32) void {
|
||||
const property_int: c_int = switch (property) {
|
||||
inline else => |val| @intCast(@intFromEnum(val)),
|
||||
};
|
||||
|
||||
cdef.GuiSetStyle(control, property_int, @as(c_int, value));
|
||||
}
|
||||
|
||||
/// Get one style property
|
||||
pub fn guiGetStyle(control: GuiControl, comptime property: anytype) i32 {
|
||||
comptime var property_int: c_int = undefined;
|
||||
|
||||
comptime {
|
||||
if (@TypeOf(property) == GuiControlProperty) {
|
||||
property_int = @intCast(@intFromEnum(property));
|
||||
} else if (@TypeOf(property) == GuiDefaultProperty) { // comparison can't be chained :(
|
||||
property_int = @intCast(@intFromEnum(property));
|
||||
} else {
|
||||
@compileError("Invalid property type for guiGetStyle");
|
||||
}
|
||||
}
|
||||
pub fn getStyle(control: Control, comptime property: ControlOrDefaultProperty) i32 {
|
||||
const property_int: c_int = switch (property) {
|
||||
inline else => |val| @intCast(@intFromEnum(val)),
|
||||
};
|
||||
|
||||
return @as(i32, cdef.GuiGetStyle(control, property_int));
|
||||
}
|
||||
|
||||
/// Get raygui icons data pointer
|
||||
pub fn guiGetIcons() RayguiError![]u32 {
|
||||
pub fn getIcons() RayguiError![]u32 {
|
||||
var res: []u32 = undefined;
|
||||
|
||||
const ptr = cdef.GuiGetIcons();
|
||||
@ -466,22 +456,22 @@ pub fn guiGetIcons() RayguiError![]u32 {
|
||||
|
||||
// If you REALLY need the return value of the function, you'll know what to do with it and its size yourself
|
||||
/// Load raygui icons file (.rgi) into internal icons data
|
||||
pub fn guiLoadIcons(fileName: [*c]const u8, loadIconsName: bool) [*c][*c]u8 {
|
||||
pub fn loadIcons(fileName: [*c]const u8, loadIconsName: bool) [*c][*c]u8 {
|
||||
return cdef.GuiLoadIcons(fileName, loadIconsName);
|
||||
}
|
||||
|
||||
/// Tab Bar control, returns TAB to be closed or -1
|
||||
pub fn guiTabBar(bounds: Rectangle, text: [][*:0]const u8, active: *i32) i32 {
|
||||
pub fn tabBar(bounds: Rectangle, text: [][*:0]const u8, active: *i32) i32 {
|
||||
return @as(i32, cdef.GuiTabBar(bounds, @as([*c][*c]const u8, @ptrCast(text)), @as(c_int, @intCast(text.len)), @as([*c]c_int, @ptrCast(active))));
|
||||
}
|
||||
|
||||
/// List View with extended parameters
|
||||
pub fn guiListViewEx(bounds: Rectangle, text: [][*:0]const u8, scrollIndex: *i32, active: *i32, focus: *i32) i32 {
|
||||
pub fn listViewEx(bounds: Rectangle, text: [][*:0]const u8, scrollIndex: *i32, active: *i32, focus: *i32) i32 {
|
||||
return @as(i32, cdef.GuiListViewEx(bounds, @as([*c][*c]const u8, @ptrCast(text)), @as(c_int, @intCast(text.len)), @as([*c]c_int, @ptrCast(scrollIndex)), @as([*c]c_int, @ptrCast(active)), @as([*c]c_int, @ptrCast(focus))));
|
||||
}
|
||||
|
||||
/// Panel control, useful to group controls
|
||||
pub fn guiPanel(bounds: Rectangle, text: ?[*:0]const u8) i32 {
|
||||
pub fn panel(bounds: Rectangle, text: ?[*:0]const u8) i32 {
|
||||
var textFinal = @as([*c]const u8, 0);
|
||||
if (text) |textSure| {
|
||||
textFinal = @as([*c]const u8, @ptrCast(textSure));
|
||||
@ -490,10 +480,31 @@ pub fn guiPanel(bounds: Rectangle, text: ?[*:0]const u8) i32 {
|
||||
}
|
||||
|
||||
/// Scroll Panel control
|
||||
pub fn guiScrollPanel(bounds: Rectangle, text: ?[*:0]const u8, content: Rectangle, scroll: *Vector2, view: *Rectangle) i32 {
|
||||
pub fn scrollPanel(bounds: Rectangle, text: ?[*:0]const u8, content: Rectangle, scroll: *Vector2, view: *Rectangle) i32 {
|
||||
var textFinal = @as([*c]const u8, 0);
|
||||
if (text) |textSure| {
|
||||
textFinal = @as([*c]const u8, @ptrCast(textSure));
|
||||
}
|
||||
return @as(i32, cdef.GuiScrollPanel(bounds, textFinal, content, @as([*c]Vector2, @ptrCast(scroll)), @as([*c]Rectangle, @ptrCast(view))));
|
||||
}
|
||||
|
||||
/// Button control, returns true when clicked
|
||||
pub fn button(bounds: Rectangle, text: [:0]const u8) bool {
|
||||
return @as(i32, cdef.GuiButton(bounds, @as([*c]const u8, @ptrCast(text)))) > 0;
|
||||
}
|
||||
|
||||
/// Label button control, returns true when clicked
|
||||
pub fn labelButton(bounds: Rectangle, text: [:0]const u8) bool {
|
||||
return @as(i32, cdef.GuiLabelButton(bounds, @as([*c]const u8, @ptrCast(text)))) > 0;
|
||||
}
|
||||
|
||||
/// Check Box control, returns true when active
|
||||
pub fn checkBox(bounds: Rectangle, text: [:0]const u8, checked: *bool) bool {
|
||||
return @as(i32, cdef.GuiCheckBox(bounds, @as([*c]const u8, @ptrCast(text)), @as([*c]bool, @ptrCast(checked)))) > 0;
|
||||
}
|
||||
|
||||
/// Text Box control, updates input text
|
||||
/// Returns true on ENTER pressed (useful for data validation)
|
||||
pub fn textBox(bounds: Rectangle, text: [:0]u8, textSize: i32, editMode: bool) bool {
|
||||
return @as(i32, cdef.GuiTextBox(bounds, @as([*c]u8, @ptrCast(text)), @as(c_int, textSize), editMode)) > 0;
|
||||
}
|
||||
|
||||
@ -8,17 +8,26 @@ pub const cdef = @import("raylib-ext.zig");
|
||||
pub const gl = @import("rlgl.zig");
|
||||
pub const math = @import("raymath.zig");
|
||||
|
||||
const C = std.builtin.CallingConvention.c;
|
||||
|
||||
test {
|
||||
std.testing.refAllDeclsRecursive(@This());
|
||||
}
|
||||
|
||||
pub const RaylibError = error{
|
||||
LoadFileData,
|
||||
CompressData,
|
||||
DecompressData,
|
||||
EncodeDataBase64,
|
||||
DecodeDataBase64,
|
||||
ExportImageToMemory,
|
||||
LoadImageColors,
|
||||
LoadImagePalette,
|
||||
LoadFont,
|
||||
LoadFontData,
|
||||
LoadCodepoints,
|
||||
LoadTextLines,
|
||||
TextSplit,
|
||||
LoadMaterial,
|
||||
LoadMaterials,
|
||||
LoadModelAnimations,
|
||||
@ -31,6 +40,7 @@ pub const RaylibError = error{
|
||||
LoadSound,
|
||||
LoadMusic,
|
||||
LoadAudioStream,
|
||||
GenImageFontAtlas,
|
||||
};
|
||||
|
||||
pub const Vector2 = extern struct {
|
||||
@ -41,6 +51,10 @@ pub const Vector2 = extern struct {
|
||||
return Vector2{ .x = x, .y = y };
|
||||
}
|
||||
|
||||
pub fn initVec(vec: @Vector(2, f32)) Vector2 {
|
||||
return Vector2{ .x = vec[0], .y = vec[1] };
|
||||
}
|
||||
|
||||
/// Vector with components value 0.0
|
||||
pub fn zero() Vector2 {
|
||||
return math.vector2Zero();
|
||||
@ -205,6 +219,10 @@ pub const Vector3 = extern struct {
|
||||
return Vector3{ .x = x, .y = y, .z = z };
|
||||
}
|
||||
|
||||
pub fn initVec(vec: @Vector(3, f32)) Vector3 {
|
||||
return Vector3{ .x = vec[0], .y = vec[1], .z = vec[2] };
|
||||
}
|
||||
|
||||
// Vector with components value 0.0
|
||||
pub fn zero() Vector3 {
|
||||
return math.vector3Zero();
|
||||
@ -419,6 +437,10 @@ pub const Vector4 = extern struct {
|
||||
return Vector4{ .x = x, .y = y, .z = z, .w = w };
|
||||
}
|
||||
|
||||
pub fn initVec(vec: @Vector(4, f32)) Vector4 {
|
||||
return Vector4{ .x = vec[0], .y = vec[1], .z = vec[2], .w = vec[2] };
|
||||
}
|
||||
|
||||
/// Vector with components value 0.0
|
||||
pub fn zero() Vector4 {
|
||||
return math.vector4Zero();
|
||||
@ -1270,7 +1292,7 @@ pub const NPatchInfo = extern struct {
|
||||
top: c_int,
|
||||
right: c_int,
|
||||
bottom: c_int,
|
||||
layout: c_int,
|
||||
layout: NPatchType,
|
||||
};
|
||||
|
||||
pub const GlyphInfo = extern struct {
|
||||
@ -1404,6 +1426,11 @@ pub const Mesh = extern struct {
|
||||
pub fn drawInstanced(self: Mesh, material: Material, transforms: []const Matrix) void {
|
||||
rl.drawMeshInstanced(self, material, transforms);
|
||||
}
|
||||
|
||||
/// Unload mesh data from CPU and GPU
|
||||
pub fn unload(self: Mesh) void {
|
||||
rl.unloadMesh(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Shader = extern struct {
|
||||
@ -1419,6 +1446,11 @@ pub const Shader = extern struct {
|
||||
pub fn deactivate(_: Shader) void {
|
||||
rl.endShaderMode();
|
||||
}
|
||||
|
||||
/// Unload shader from GPU memory (VRAM)
|
||||
pub fn unload(self: Shader) void {
|
||||
rl.unloadShader(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const MaterialMap = extern struct {
|
||||
@ -1431,6 +1463,11 @@ pub const Material = extern struct {
|
||||
shader: Shader,
|
||||
maps: [*c]MaterialMap,
|
||||
params: [4]f32,
|
||||
|
||||
/// Unload material from GPU memory (VRAM)
|
||||
pub fn unload(self: Material) void {
|
||||
rl.unloadMaterial(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Transform = extern struct {
|
||||
@ -1497,6 +1534,11 @@ pub const ModelAnimation = extern struct {
|
||||
bones: [*c]BoneInfo,
|
||||
framePoses: [*c][*c]Transform,
|
||||
name: [32]u8,
|
||||
|
||||
/// Unload animation data
|
||||
pub fn unload(self: ModelAnimation) void {
|
||||
rl.unloadModelAnimation(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Ray = extern struct {
|
||||
@ -1522,6 +1564,11 @@ pub const Wave = extern struct {
|
||||
sampleSize: c_uint,
|
||||
channels: c_uint,
|
||||
data: *anyopaque,
|
||||
|
||||
/// Unload wave data
|
||||
pub fn unload(self: Wave) void {
|
||||
rl.unloadWave(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const rAudioBuffer = opaque {};
|
||||
@ -1533,11 +1580,21 @@ pub const AudioStream = extern struct {
|
||||
sampleRate: c_uint,
|
||||
sampleSize: c_uint,
|
||||
channels: c_uint,
|
||||
|
||||
/// Unload audio stream and free memory
|
||||
pub fn unload(self: AudioStream) void {
|
||||
rl.unloadAudioStream(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Sound = extern struct {
|
||||
stream: AudioStream,
|
||||
frameCount: c_uint,
|
||||
|
||||
/// Unload sound
|
||||
pub fn unload(self: Sound) void {
|
||||
rl.unloadSound(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const Music = extern struct {
|
||||
@ -1546,6 +1603,11 @@ pub const Music = extern struct {
|
||||
looping: bool,
|
||||
ctxType: c_int,
|
||||
ctxData: *anyopaque,
|
||||
|
||||
/// Unload music stream
|
||||
pub fn unload(self: Music) void {
|
||||
rl.unloadMusicStream(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const VrDeviceInfo = extern struct {
|
||||
@ -1570,6 +1632,11 @@ pub const VrStereoConfig = extern struct {
|
||||
rightScreenCenter: [2]f32,
|
||||
scale: [2]f32,
|
||||
scaleIn: [2]f32,
|
||||
|
||||
/// Unload VR stereo config
|
||||
pub fn unload(self: VrStereoConfig) void {
|
||||
rl.unloadVrStereoConfig(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const FilePathList = extern struct {
|
||||
@ -1584,7 +1651,16 @@ pub const AutomationEvent = extern struct {
|
||||
params: [4]c_int,
|
||||
};
|
||||
|
||||
pub const AutomationEventList = extern struct { capacity: c_uint, count: c_uint, events: [*c]AutomationEvent };
|
||||
pub const AutomationEventList = extern struct {
|
||||
capacity: c_uint,
|
||||
count: c_uint,
|
||||
events: [*c]AutomationEvent,
|
||||
|
||||
/// Unload automation events list from file
|
||||
pub fn unload(self: AutomationEventList) void {
|
||||
rl.unloadAutomationEventList(self);
|
||||
}
|
||||
};
|
||||
|
||||
pub const ConfigFlags = packed struct {
|
||||
__reserved: bool = false,
|
||||
@ -1843,6 +1919,8 @@ pub const ShaderLocationIndex = enum(c_int) {
|
||||
vertex_boneids = 26,
|
||||
vertex_boneweights = 27,
|
||||
bone_matrices = 28,
|
||||
shader_loc_vertex_instance_tx = 29,
|
||||
//
|
||||
};
|
||||
|
||||
pub const ShaderUniformDataType = enum(c_int) {
|
||||
@ -1932,18 +2010,23 @@ pub const BlendMode = enum(c_int) {
|
||||
custom_separate = 7,
|
||||
};
|
||||
|
||||
pub const Gesture = enum(c_int) {
|
||||
none = 0,
|
||||
tap = 1,
|
||||
doubletap = 2,
|
||||
hold = 4,
|
||||
drag = 8,
|
||||
swipe_right = 16,
|
||||
swipe_left = 32,
|
||||
swipe_up = 64,
|
||||
swipe_down = 128,
|
||||
pinch_in = 256,
|
||||
pinch_out = 512,
|
||||
pub const Gesture = packed struct {
|
||||
tap: bool = false,
|
||||
doubletap: bool = false,
|
||||
hold: bool = false,
|
||||
drag: bool = false,
|
||||
swipe_right: bool = false,
|
||||
swipe_left: bool = false,
|
||||
swipe_up: bool = false,
|
||||
swipe_down: bool = false,
|
||||
pinch_in: bool = false,
|
||||
pinch_out: bool = false,
|
||||
__reserved1: bool = false,
|
||||
__reserved2: bool = false,
|
||||
__reserved3: bool = false,
|
||||
__reserved4: bool = false,
|
||||
__reserved5: bool = false,
|
||||
__reserved6: bool = false,
|
||||
};
|
||||
|
||||
pub const CameraMode = enum(c_int) {
|
||||
@ -1965,17 +2048,17 @@ pub const NPatchType = enum(c_int) {
|
||||
three_patch_horizontal = 2,
|
||||
};
|
||||
|
||||
// pub const TraceLogCallback = ?fn (c_int, [*c]const u8, [*c]struct___va_list_tag) callconv(.C) void;
|
||||
pub const LoadFileDataCallback = *const fn ([*c]const u8, [*c]c_uint) callconv(.C) [*c]u8;
|
||||
pub const SaveFileDataCallback = *const fn ([*c]const u8, ?*anyopaque, c_uint) callconv(.C) bool;
|
||||
pub const LoadFileTextCallback = *const fn ([*c]const u8) callconv(.C) [*c]u8;
|
||||
pub const SaveFileTextCallback = *const fn ([*c]const u8, [*c]u8) callconv(.C) bool;
|
||||
pub const AudioCallback = ?*const fn (?*anyopaque, c_uint) callconv(.C) void;
|
||||
// pub const TraceLogCallback = ?fn (c_int, [*c]const u8, [*c]struct___va_list_tag) callconv(C) void;
|
||||
pub const LoadFileDataCallback = *const fn ([*c]const u8, [*c]c_uint) callconv(C) [*c]u8;
|
||||
pub const SaveFileDataCallback = *const fn ([*c]const u8, ?*anyopaque, c_uint) callconv(C) bool;
|
||||
pub const LoadFileTextCallback = *const fn ([*c]const u8) callconv(C) [*c]u8;
|
||||
pub const SaveFileTextCallback = *const fn ([*c]const u8, [*c]u8) callconv(C) bool;
|
||||
pub const AudioCallback = ?*const fn (?*anyopaque, c_uint) callconv(C) void;
|
||||
|
||||
pub const RAYLIB_VERSION_MAJOR = @as(i32, 5);
|
||||
pub const RAYLIB_VERSION_MINOR = @as(i32, 5);
|
||||
pub const RAYLIB_VERSION_PATCH = @as(i32, 0);
|
||||
pub const RAYLIB_VERSION = "5.5";
|
||||
pub const RAYLIB_VERSION = "5.6-dev";
|
||||
|
||||
pub const MAX_TOUCH_POINTS = 10;
|
||||
pub const MAX_MATERIAL_MAPS = 12;
|
||||
@ -2021,16 +2104,13 @@ pub fn loadShaderFromMemory(vsCode: ?[:0]const u8, fsCode: ?[:0]const u8) Raylib
|
||||
return if (isValid) shader else RaylibError.LoadShader;
|
||||
}
|
||||
|
||||
/// Load file data as byte array (read)
|
||||
pub fn loadFileData(fileName: [:0]const u8) RaylibError![]u8 {
|
||||
var bytesRead: i32 = 0;
|
||||
var res: []u8 = undefined;
|
||||
pub fn loadRandomSequence(count: u32, min: i32, max: i32) []i32 {
|
||||
var res: []i32 = undefined;
|
||||
|
||||
const ptr = cdef.LoadFileData(@as([*c]const u8, @ptrCast(fileName)), @as([*c]c_int, @ptrCast(&bytesRead)));
|
||||
if (ptr == 0) return RaylibError.LoadFileData;
|
||||
const ptr = cdef.LoadRandomSequence(@as(c_uint, @intCast(count)), @as(c_int, @intCast(min)), @as(c_int, @intCast(max)));
|
||||
|
||||
res.ptr = @as([*]u8, @ptrCast(ptr));
|
||||
res.len = @as(usize, @intCast(bytesRead));
|
||||
res.ptr = @as([*]i32, @ptrCast(ptr));
|
||||
res.len = @as(usize, @intCast(count));
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -2044,42 +2124,6 @@ pub fn exportDataAsCode(data: []const u8, fileName: [:0]const u8) bool {
|
||||
return cdef.ExportDataAsCode(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]const u8, @ptrCast(fileName)));
|
||||
}
|
||||
|
||||
/// Compress data (DEFLATE algorithm), memory must be MemFree()
|
||||
pub fn compressData(data: []const u8) []u8 {
|
||||
var compDataSize: i32 = 0;
|
||||
var res: []u8 = undefined;
|
||||
res.ptr = cdef.CompressData(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]c_int, @ptrCast(&compDataSize)));
|
||||
res.len = @as(usize, @intCast(compDataSize));
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Decompress data (DEFLATE algorithm), memory must be MemFree()
|
||||
pub fn decompressData(compData: []const u8) []u8 {
|
||||
var dataSize: i32 = 0;
|
||||
var res: []u8 = undefined;
|
||||
res.ptr = cdef.DecompressData(@as([*c]const u8, @ptrCast(compData)), @as(c_int, @intCast(compData.len)), @as([*c]c_int, @ptrCast(&dataSize)));
|
||||
res.len = @as(usize, @intCast(dataSize));
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Encode data to Base64 string, memory must be MemFree()
|
||||
pub fn encodeDataBase64(data: []const u8) []u8 {
|
||||
var outputSize: i32 = 0;
|
||||
var res: []u8 = undefined;
|
||||
res.ptr = cdef.EncodeDataBase64(@as([*c]const u8, @ptrCast(data)), @as(c_int, @intCast(data.len)), @as([*c]c_int, @ptrCast(&outputSize)));
|
||||
res.len = @as(usize, @intCast(outputSize));
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Decode Base64 string data, memory must be MemFree()
|
||||
pub fn decodeDataBase64(data: []const u8) []u8 {
|
||||
var outputSize: i32 = 0;
|
||||
var res: []u8 = undefined;
|
||||
res.ptr = cdef.DecodeDataBase64(@as([*c]const u8, @ptrCast(data)), @as([*c]c_int, @ptrCast(&outputSize)));
|
||||
res.len = @as(usize, @intCast(outputSize));
|
||||
return res;
|
||||
}
|
||||
|
||||
pub fn computeCRC32(data: []u8) u32 {
|
||||
return cdef.ComputeCRC32(@as([*c]u8, @ptrCast(data)), @as(c_int, @intCast(data.len)));
|
||||
}
|
||||
@ -2170,19 +2214,6 @@ pub fn loadImageColors(image: Image) RaylibError![]Color {
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Load colors palette from image as a Color array (RGBA - 32bit)
|
||||
pub fn loadImagePalette(image: Image, maxPaletteSize: i32) RaylibError![]Color {
|
||||
var colorCount: i32 = 0;
|
||||
var res: []Color = undefined;
|
||||
|
||||
const ptr = cdef.LoadImagePalette(image, @as(c_int, maxPaletteSize), @as([*c]c_int, @ptrCast(&colorCount)));
|
||||
if (ptr == 0) return RaylibError.LoadImagePalette;
|
||||
|
||||
res.ptr = @as([*]Color, @ptrCast(ptr));
|
||||
res.len = @as(usize, @intCast(colorCount));
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Load texture from file into GPU memory (VRAM)
|
||||
pub fn loadTexture(fileName: [:0]const u8) RaylibError!Texture2D {
|
||||
const texture = cdef.LoadTexture(@as([*c]const u8, @ptrCast(fileName)));
|
||||
@ -2234,11 +2265,11 @@ pub fn loadFont(fileName: [:0]const u8) RaylibError!Font {
|
||||
}
|
||||
|
||||
/// Load font from file with extended parameters, use null for fontChars to load the default character set
|
||||
pub fn loadFontEx(fileName: [:0]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font {
|
||||
var fontCharsFinal = @as([*c]c_int, 0);
|
||||
pub fn loadFontEx(fileName: [:0]const u8, fontSize: i32, fontChars: ?[]const i32) RaylibError!Font {
|
||||
var fontCharsFinal = @as([*c]const c_int, 0);
|
||||
var fontCharsLen: c_int = @as(c_int, 0);
|
||||
if (fontChars) |fontCharsSure| {
|
||||
fontCharsFinal = @as([*c]c_int, @ptrCast(fontCharsSure));
|
||||
fontCharsFinal = @as([*c]const c_int, @ptrCast(fontCharsSure));
|
||||
fontCharsLen = @as(i32, @intCast(fontCharsSure.len));
|
||||
}
|
||||
const font = cdef.LoadFontEx(@as([*c]const u8, @ptrCast(fileName)), @as(c_int, fontSize), fontCharsFinal, fontCharsLen);
|
||||
@ -2247,7 +2278,7 @@ pub fn loadFontEx(fileName: [:0]const u8, fontSize: i32, fontChars: ?[]i32) Rayl
|
||||
}
|
||||
|
||||
/// Load font from memory buffer, fileType refers to extension: i.e. '.ttf'
|
||||
pub fn loadFontFromMemory(fileType: [:0]const u8, fileData: ?[]const u8, fontSize: i32, fontChars: ?[]i32) RaylibError!Font {
|
||||
pub fn loadFontFromMemory(fileType: [:0]const u8, fileData: ?[]const u8, fontSize: i32, fontChars: ?[]const i32) RaylibError!Font {
|
||||
var fileDataFinal = @as([*c]const u8, 0);
|
||||
var fileDataLen: i32 = 0;
|
||||
if (fileData) |fileDataSure| {
|
||||
@ -2255,7 +2286,7 @@ pub fn loadFontFromMemory(fileType: [:0]const u8, fileData: ?[]const u8, fontSiz
|
||||
fileDataLen = @as(i32, @intCast(fileDataSure.len));
|
||||
}
|
||||
const codepointCount: c_int = if (fontChars) |fontCharsSure| @intCast(fontCharsSure.len) else 0;
|
||||
const font = cdef.LoadFontFromMemory(@as([*c]const u8, @ptrCast(fileType)), @as([*c]const u8, @ptrCast(fileDataFinal)), @as(c_int, @intCast(fileDataLen)), @as(c_int, fontSize), @as([*c]c_int, @ptrCast(fontChars)), codepointCount);
|
||||
const font = cdef.LoadFontFromMemory(@as([*c]const u8, @ptrCast(fileType)), @as([*c]const u8, @ptrCast(fileDataFinal)), @as(c_int, @intCast(fileDataLen)), @as(c_int, fontSize), @as([*c]const c_int, @ptrCast(fontChars)), codepointCount);
|
||||
const isValid = cdef.IsFontValid(font);
|
||||
return if (isValid) font else RaylibError.LoadFont;
|
||||
}
|
||||
@ -2268,30 +2299,23 @@ pub fn loadFontFromImage(image: Image, key: Color, firstChar: i32) RaylibError!F
|
||||
}
|
||||
|
||||
/// Load font data for further use
|
||||
pub fn loadFontData(fileData: []const u8, fontSize: i32, fontChars: []i32, ty: FontType) RaylibError![]GlyphInfo {
|
||||
pub fn loadFontData(fileData: []const u8, fontSize: i32, codePoints: ?[]const i32, ty: FontType) RaylibError![]GlyphInfo {
|
||||
var res: []GlyphInfo = undefined;
|
||||
|
||||
const ptr = cdef.LoadFontData(@as([*c]const u8, @ptrCast(fileData)), @as(c_int, @intCast(fileData.len)), @as(c_int, fontSize), @as([*c]c_int, @ptrCast(fontChars)), @as(c_int, @intCast(fontChars.len)), ty);
|
||||
var codePointsFinal = @as([*c]const i32, 0);
|
||||
var codePointsLen: i32 = 0;
|
||||
if (codePoints) |codePointsSure| {
|
||||
codePointsFinal = @as([*c]const i32, @ptrCast(codePointsSure));
|
||||
codePointsLen = @as(i32, @intCast(codePointsSure.len));
|
||||
} else {
|
||||
codePointsLen = 95;
|
||||
}
|
||||
|
||||
const ptr = cdef.LoadFontData(@as([*c]const u8, @ptrCast(fileData)), @as(c_int, @intCast(fileData.len)), @as(c_int, fontSize), codePointsFinal, @as(c_int, @intCast(codePointsLen)), ty, @as([*c]i32, &codePointsLen));
|
||||
if (ptr == 0) return RaylibError.LoadFontData;
|
||||
|
||||
res.ptr = @as([*]GlyphInfo, @ptrCast(ptr));
|
||||
res.len = @as(usize, @intCast(fontChars.len));
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Load all codepoints from a UTF-8 text string, codepoints count returned by parameter
|
||||
pub fn loadCodepoints(text: [:0]const u8) RaylibError![]i32 {
|
||||
if (@sizeOf(c_int) != @sizeOf(i32)) {
|
||||
@compileError("Can't cast pointer to c_int array to i32 because they don't have the same size");
|
||||
}
|
||||
var count: i32 = 0;
|
||||
var res: []i32 = undefined;
|
||||
|
||||
const ptr = cdef.LoadCodepoints(@as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(&count)));
|
||||
if (ptr == 0) return RaylibError.LoadCodepoints;
|
||||
|
||||
res.ptr = @as([*]i32, @ptrCast(ptr));
|
||||
res.len = @as(usize, @intCast(count));
|
||||
res.len = @as(usize, @intCast(codePointsLen));
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -2300,8 +2324,8 @@ pub fn textFormat(text: [:0]const u8, args: anytype) [:0]const u8 {
|
||||
comptime {
|
||||
const info = @typeInfo(@TypeOf(args));
|
||||
switch (info) {
|
||||
.Struct => {
|
||||
if (!info.Struct.is_tuple)
|
||||
.@"struct" => {
|
||||
if (!info.@"struct".is_tuple)
|
||||
@compileError("Args should be in a tuple (call this function like textFormat(.{arg1, arg2, ...});)!");
|
||||
},
|
||||
else => {
|
||||
@ -2318,8 +2342,8 @@ pub fn traceLog(logLevel: TraceLogLevel, text: [:0]const u8, args: anytype) void
|
||||
comptime {
|
||||
const info = @typeInfo(@TypeOf(args));
|
||||
switch (info) {
|
||||
.Struct => {
|
||||
if (!info.Struct.is_tuple)
|
||||
.@"struct" => {
|
||||
if (!info.@"struct".is_tuple)
|
||||
@compileError("Args should be in a tuple (call this function like traceLog(.{arg1, arg2, ...});)!");
|
||||
},
|
||||
else => {
|
||||
@ -2331,15 +2355,6 @@ pub fn traceLog(logLevel: TraceLogLevel, text: [:0]const u8, args: anytype) void
|
||||
@call(.auto, cdef.TraceLog, .{ logLevel, @as([*c]const u8, @ptrCast(text)) } ++ args);
|
||||
}
|
||||
|
||||
/// Split text into multiple strings
|
||||
pub fn textSplit(text: [:0]const u8, delimiter: u8) [][:0]const u8 {
|
||||
var count: i32 = 0;
|
||||
var res: [][:0]const u8 = undefined;
|
||||
res.ptr = @as([*][:0]const u8, @ptrCast(cdef.TextSplit(@as([*c]const u8, @ptrCast(text)), delimiter, @as([*c]c_int, @ptrCast(&count)))));
|
||||
res.len = @as(usize, @intCast(count));
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Draw multiple mesh instances with material and different transforms
|
||||
pub fn drawMeshInstanced(mesh: Mesh, material: Material, transforms: []const Matrix) void {
|
||||
cdef.DrawMeshInstanced(mesh, material, @as([*c]const Matrix, @ptrCast(transforms)), @as(c_int, @intCast(transforms.len)));
|
||||
@ -2385,19 +2400,6 @@ pub fn loadModelFromMesh(mesh: Mesh) RaylibError!Model {
|
||||
return if (isValid) model else RaylibError.LoadModel;
|
||||
}
|
||||
|
||||
/// Load model animations from file
|
||||
pub fn loadModelAnimations(fileName: [:0]const u8) RaylibError![]ModelAnimation {
|
||||
var animCount: i32 = 0;
|
||||
var res: []ModelAnimation = undefined;
|
||||
|
||||
const ptr = cdef.LoadModelAnimations(@as([*c]const u8, @ptrCast(fileName)), @as([*c]c_int, @ptrCast(&animCount)));
|
||||
if (ptr == 0) return RaylibError.LoadModelAnimations;
|
||||
|
||||
res.ptr = @as([*]ModelAnimation, @ptrCast(ptr));
|
||||
res.len = @as(usize, @intCast(animCount));
|
||||
return res;
|
||||
}
|
||||
|
||||
/// Unload animation data
|
||||
pub fn unloadModelAnimations(animations: []ModelAnimation) void {
|
||||
cdef.UnloadModelAnimations(@as([*c]ModelAnimation, @ptrCast(animations)), @as(c_int, @intCast(animations.len)));
|
||||
@ -2503,10 +2505,18 @@ pub fn imageKernelConvolution(image: *Image, kernel: []const f32) void {
|
||||
}
|
||||
|
||||
/// Generate image font atlas using chars info
|
||||
pub fn genImageFontAtlas(chars: []const GlyphInfo, recs: [][]Rectangle, fontSize: i32, padding: i32, packMethod: i32) RaylibError!Image {
|
||||
const image = cdef.GenImageFontAtlas(@as([*c]const GlyphInfo, @ptrCast(chars)), @as([*c][*c]Rectangle, @ptrCast(recs)), @as(c_int, @intCast(recs.len)), @as(c_int, fontSize), @as(c_int, padding), @as(c_int, packMethod));
|
||||
pub fn genImageFontAtlas(glyphs: []const GlyphInfo, fontSize: i32, padding: i32, packMethod: i32) RaylibError!struct { Image, []Rectangle } {
|
||||
var res: []Rectangle = undefined;
|
||||
var recs: [*c]Rectangle = 0;
|
||||
const image = cdef.GenImageFontAtlas(@as([*c]const GlyphInfo, @ptrCast(glyphs)), @as([*c][*c]Rectangle, @ptrCast(&recs)), @as(c_int, @intCast(glyphs.len)), @as(c_int, fontSize), @as(c_int, padding), @as(c_int, packMethod));
|
||||
const isValid = cdef.IsImageValid(image);
|
||||
return if (isValid) image else RaylibError.LoadImage;
|
||||
|
||||
if (!isValid) return RaylibError.GenImageFontAtlas;
|
||||
|
||||
res.ptr = @as([*]Rectangle, @ptrCast(@alignCast(recs)));
|
||||
res.len = @as(usize, @intCast(glyphs.len));
|
||||
|
||||
return .{ image, res };
|
||||
}
|
||||
|
||||
/// Unload font chars info data (RAM)
|
||||
@ -2524,9 +2534,27 @@ pub fn loadUTF8(codepoints: []const c_int) [:0]u8 {
|
||||
return std.mem.span(cdef.LoadUTF8(@as([*c]const c_int, @ptrCast(codepoints)), @as(c_int, @intCast(codepoints.len))));
|
||||
}
|
||||
|
||||
// Load text as separate lines ('\n')
|
||||
pub fn loadTextLines(text: [:0]const u8) RaylibError![][:0]u8 {
|
||||
var lineCount: i32 = 0;
|
||||
var res: [][:0]u8 = undefined;
|
||||
|
||||
const ptr = cdef.LoadTextLines(@as([*c]const u8, @ptrCast(text)), @as([*c]c_int, @ptrCast(&lineCount)));
|
||||
if (ptr == 0) return RaylibError.LoadTextLines;
|
||||
|
||||
res.ptr = @as([*][:0]u8, @ptrCast(ptr));
|
||||
res.len = @as(usize, @intCast(lineCount));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
pub fn unloadTextLines(lines: [][:0]u8) void {
|
||||
cdef.UnloadTextLines(@as([*c][*c]u8, @ptrCast(lines)), @as(c_int, @intCast(lines.len)));
|
||||
}
|
||||
|
||||
/// Join text strings with delimiter
|
||||
pub fn textJoin(textList: [][:0]const u8, delimiter: [:0]const u8) [:0]const u8 {
|
||||
return std.mem.span(cdef.TextJoin(@as([*c][*c]const u8, @ptrCast(textList)), @as(c_int, @intCast(textList.len)), @as([*c]const u8, @ptrCast(delimiter))));
|
||||
pub fn textJoin(textList: [][:0]u8, delimiter: [:0]const u8) [:0]const u8 {
|
||||
return std.mem.span(cdef.TextJoin(@as([*c][*c]u8, @ptrCast(textList)), @as(c_int, @intCast(textList.len)), @as([*c]const u8, @ptrCast(delimiter))));
|
||||
}
|
||||
|
||||
/// Draw a triangle strip defined by points
|
||||
@ -2535,24 +2563,33 @@ pub fn drawTriangleStrip3D(points: []const Vector3, color: Color) void {
|
||||
}
|
||||
|
||||
/// Internal memory allocator
|
||||
fn alloc(_: *anyopaque, len: usize, _: u8, _: usize) ?[*]u8 {
|
||||
fn alloc(_: *anyopaque, len: usize, _: std.mem.Alignment, _: usize) ?[*]u8 {
|
||||
std.debug.assert(len > 0);
|
||||
return @ptrCast(cdef.MemAlloc(@intCast(len)));
|
||||
}
|
||||
|
||||
fn resize(_: *anyopaque, buf: []u8, _: u8, new_len: usize, _: usize) bool {
|
||||
fn resize(_: *anyopaque, buf: []u8, _: std.mem.Alignment, new_len: usize, _: usize) bool {
|
||||
return (new_len <= buf.len);
|
||||
}
|
||||
|
||||
/// Internal memory free
|
||||
fn free(_: *anyopaque, buf: []u8, _: u8, _: usize) void {
|
||||
fn free(_: *anyopaque, buf: []u8, _: std.mem.Alignment, _: usize) void {
|
||||
cdef.MemFree(buf.ptr);
|
||||
}
|
||||
|
||||
fn remap(_: *anyopaque, buf: []u8, _: std.mem.Alignment, new_len: usize, _: usize) ?[*]u8 {
|
||||
if (new_len <= buf.len) {
|
||||
return buf.ptr;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const mem_vtable = std.mem.Allocator.VTable{
|
||||
.alloc = alloc,
|
||||
.resize = resize,
|
||||
.free = free,
|
||||
.remap = remap,
|
||||
};
|
||||
|
||||
pub const mem = std.mem.Allocator{
|
||||
|
||||