diff --git a/.gitignore b/.gitignore index 041b96e..1bb26fd 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,7 @@ build/ -misc/ +compile_commands.json +.cache/ +.ccls-cache/ +builddir +automate.txt +.vscode/ \ No newline at end of file diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..665ba2b --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "subprojects/raylib/source"] + path = subprojects/raylib/source + url = https://github.com/raysan5/raylib diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index dc47e9d..0000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "C_Cpp.default.compileCommands": "build/vscode_compile_commands.json" -} diff --git a/.vscode/vapi.code-snippets b/.vscode/vapi.code-snippets deleted file mode 100644 index d56a360..0000000 --- a/.vscode/vapi.code-snippets +++ /dev/null @@ -1,24 +0,0 @@ -{ - // Place your raylib-vapi workspace snippets here. Each snippet is defined under a snippet name and has a scope, prefix, body and - // description. Add comma separated ids of the languages where the snippet is applicable in the scope field. If scope - // is left empty or omitted, the snippet gets applied to all languages. The prefix is what is - // used to trigger the snippet and the body will be expanded and inserted. Possible variables are: - // $1, $2 for tab stops, $0 for the final cursor position, and ${1:label}, ${2:another} for placeholders. - // Placeholders with the same ids are connected. - // Example: - // "Print to console": { - // "scope": "javascript,typescript", - // "prefix": "log", - // "body": [ - // "console.log('$1');", - // "$2" - // ], - // "description": "Log output to console" - // } - - "CCode": { - "scope": "vapi,vala", - "prefix": "ccode", - "body": "[CCode (cname = \"$1\")]$0" - } -} diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8ba1f31 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,2 @@ +# Contributing + diff --git a/README.md b/README.md index e3b15bd..2851db0 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ public static int main (string[] args) { ``` ## Compiling Included Examples -```powershell +```bash cd examples meson build -C build diff --git a/compose.yaml b/compose.yaml new file mode 100644 index 0000000..8d2609d --- /dev/null +++ b/compose.yaml @@ -0,0 +1,84 @@ +version: '1.0' + +services: + rolling: + build: + context: . + dockerfile: dockerfiles/rolling + working_dir: /project + environment: + - PULSE_SERVER=/tmp/pulse/native + - WAYLAND_DISPLAY=${WAYLAND_DISPLAY} + - DISPLAY=${DISPLAY} + - G_MESSAGES_DEBUG=all + - CCACHE_DIR=/ccache + volumes: + - type: bind + source: /dev/dri + target: /dev/dri + - type: bind + source: /tmp/.X11-unix + target: /tmp/.X11-unix + - type: bind + source: ${XDG_RUNTIME_DIR}/pulse + target: /tmp/pulse + - type: bind + source: . + target: /project + - type: bind + source: ${HOME}/.cache/raylib_oop_ccache + target: /ccache + stable: + build: + context: . + dockerfile: dockerfiles/stable + working_dir: /project + environment: + - PULSE_SERVER=/tmp/pulse/native + - WAYLAND_DISPLAY=${WAYLAND_DISPLAY} + - DISPLAY=${DISPLAY} + - G_MESSAGES_DEBUG=all + - CCACHE_DIR=/ccache + volumes: + - type: bind + source: /dev/dri + target: /dev/dri + - type: bind + source: /tmp/.X11-unix + target: /tmp/.X11-unix + - type: bind + source: ${XDG_RUNTIME_DIR}/pulse + target: /tmp/pulse + - type: bind + source: . + target: /project + - type: bind + source: ${HOME}/.cache/raylib_oop_ccache + target: /ccache + bleeding: + build: + context: . + dockerfile: dockerfiles/bleeding + working_dir: /project + environment: + - PULSE_SERVER=/tmp/pulse/native + - WAYLAND_DISPLAY=${WAYLAND_DISPLAY} + - DISPLAY=${DISPLAY} + - G_MESSAGES_DEBUG=all + - CCACHE_DIR=/ccache + volumes: + - type: bind + source: /dev/dri + target: /dev/dri + - type: bind + source: /tmp/.X11-unix + target: /tmp/.X11-unix + - type: bind + source: ${XDG_RUNTIME_DIR}/pulse + target: /tmp/pulse + - type: bind + source: . + target: /project + - type: bind + source: ${HOME}/.cache/raylib_oop_ccache + target: /ccache diff --git a/data/raylib-vapi.png b/data/raylib-vapi.png index f022ce6..208d9ca 100644 Binary files a/data/raylib-vapi.png and b/data/raylib-vapi.png differ diff --git a/dockerfiles/bleeding b/dockerfiles/bleeding new file mode 100644 index 0000000..215d811 --- /dev/null +++ b/dockerfiles/bleeding @@ -0,0 +1,7 @@ +FROM fedora:rawhide +RUN set -eux && \ + echo "fastestmirror=1" >> /etc/dnf/dnf.conf && \ + dnf update -y && \ + dnf install -y meson vala "pkgconfig(gl)" "pkgconfig(xcursor)" "pkgconfig(xrandr)" \ + "pkgconfig(xinerama)" "pkgconfig(xi)" cmake "pkgconfig(sdl2)" "pkgconfig(glfw3)" \ + "pkgconfig(libdrm)" "pkgconfig(egl)" "pkgconfig(gbm)" vim pulseaudio-libs ccache diff --git a/dockerfiles/rolling b/dockerfiles/rolling new file mode 100644 index 0000000..bfc30e5 --- /dev/null +++ b/dockerfiles/rolling @@ -0,0 +1,7 @@ +FROM fedora:latest +RUN set -eux && \ + echo "fastestmirror=1" >> /etc/dnf/dnf.conf && \ + dnf update -y && \ + dnf install -y meson vala "pkgconfig(gl)" "pkgconfig(xcursor)" "pkgconfig(xrandr)" \ + "pkgconfig(xinerama)" "pkgconfig(xi)" cmake "pkgconfig(sdl2)" "pkgconfig(glfw3)" \ + "pkgconfig(libdrm)" "pkgconfig(egl)" "pkgconfig(gbm)" vim pulseaudio-libs ccache diff --git a/dockerfiles/stable b/dockerfiles/stable new file mode 100644 index 0000000..ac5160e --- /dev/null +++ b/dockerfiles/stable @@ -0,0 +1,10 @@ +FROM almalinux:8 +RUN set -eux && \ + echo "fastestmirror=1" >> /etc/dnf/dnf.conf && \ + dnf update -y && \ + dnf install -y epel-release && \ + crb enable && \ + dnf update -y && \ + dnf install -y meson vala "pkgconfig(gl)" "pkgconfig(xcursor)" "pkgconfig(xrandr)" \ + "pkgconfig(xinerama)" "pkgconfig(xi)" cmake "pkgconfig(sdl2)" "pkgconfig(glfw3)" \ + "pkgconfig(libdrm)" "pkgconfig(egl)" "pkgconfig(gbm)" vim pulseaudio-libs ccache diff --git a/examples/Camera3D/Main.vala b/examples/Camera3D/Main.vala deleted file mode 100644 index aabf1f0..0000000 --- a/examples/Camera3D/Main.vala +++ /dev/null @@ -1,65 +0,0 @@ -using Raylib; - -public const int MAX_COLUMNS = 20; -public const int SCREEN_WIDTH = 800; -public const int SCREEN_HEIGHT = 450; - -public static int main (string[] args) { - init_window (SCREEN_WIDTH, SCREEN_HEIGHT, "raylib [core] example - 3d camera first person"); - - Camera camera = { }; - camera.position = { 4.0f, 2.0f, 4.0f }; - camera.target = { 0.0f, 1.8f, 0.0f }; - camera.up = { 0.0f, 1.0f, 0.0f }; - camera.fovy = 60.0f; - camera.projection = CameraProjection.PERSPECTIVE; - - float heights[MAX_COLUMNS]; - Vector3 positions[MAX_COLUMNS]; - Color colors[MAX_COLUMNS]; - - for (int i = 0; i < MAX_COLUMNS; i++) { - heights[i] = (float)get_random_value (1, 12); - positions[i] = { (float)get_random_value (-15, 15), heights[i] / 2.0f, (float)get_random_value (-15, 15) }; - colors[i] = { (uchar)get_random_value (20, 255), (uchar)get_random_value (10, 55), 30, 255 }; - } - - set_target_fps (60); - - // Main game loop - while (!window_should_close ()) { - update_camera (camera, CameraMode.FIRST_PERSON); - - begin_drawing (); - - clear_background (RAYWHITE); - - begin_mode_3D (camera); - - draw_plane ({ 0.0f, 0.0f, 0.0f }, { 32.0f, 32.0f }, { 200, 200, 200, 255 }); - draw_cube ({ -16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, BLUE); - draw_cube ({ 16.0f, 2.5f, 0.0f }, 1.0f, 5.0f, 32.0f, LIME); - draw_cube ({ 0.0f, 2.5f, 16.0f }, 32.0f, 5.0f, 1.0f, GOLD); - - // Draw some cubes around - for (int i = 0; i < MAX_COLUMNS; i++) { - draw_cube (positions[i], 2.0f, heights[i], 2.0f, colors[i]); - draw_cube_wires (positions[i], 2.0f, heights[i], 2.0f, MAROON); - } - - end_mode_3D (); - - draw_rectangle ( 10, 10, 220, 70, fade (SKYBLUE, 0.5f)); - draw_rectangle_lines ( 10, 10, 220, 70, BLUE); - - draw_text ("First person camera default controls:", 20, 20, 10, BLACK); - draw_text ("- Move with keys: W, A, S, D", 40, 40, 10, DARKGRAY); - draw_text ("- Mouse move to look around", 40, 60, 10, DARKGRAY); - - end_drawing (); - } - - close_window (); - - return 0; -} diff --git a/examples/Camera3D/meson.build b/examples/Camera3D/meson.build deleted file mode 100644 index 895a293..0000000 --- a/examples/Camera3D/meson.build +++ /dev/null @@ -1,7 +0,0 @@ -executable ( - 'application', - - 'Main.vala', - - dependencies: project_dependency -) diff --git a/examples/Physac/Main.vala b/examples/Physac/Main.vala deleted file mode 100644 index 0b0c35a..0000000 --- a/examples/Physac/Main.vala +++ /dev/null @@ -1,43 +0,0 @@ -using Raylib; -using Physac; - -public const int WINDOW_WIDTH = 800; -public const int WINDOW_HEIGHT = 450; - -public static int main (string[] args) { - init_window (WINDOW_WIDTH, WINDOW_HEIGHT, "raylib [core] example - basic window"); - - init_physics (); - - PhysicsBody floor = create_physics_body_rectangle ({ WINDOW_WIDTH / 2, WINDOW_HEIGHT }, 500.0f, 100.0f, 10); - floor.enabled = false; - - PhysicsBody circle = create_physics_body_circle ({ WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2 }, 45.0f, 10.0f); - circle.enabled = false; - - set_target_fps (60); - - while (!window_should_close ()) { - int body_count = get_physics_bodies_count (); - - for (int i = body_count - 1; i >= 0; i--) { - PhysicsBody? body = get_physics_body (i); - - if ((body != null) && body.position.y > WINDOW_HEIGHT * 2) { - destroy_physics_body (body); - } - } - - begin_drawing (); - clear_background (RAYWHITE); - - draw_text ("Congrats! You created your first window!", 190, 200, 20, LIGHTGRAY); - end_drawing (); - } - - close_physics (); - - close_window (); - - return 0; -} diff --git a/examples/Physac/meson.build b/examples/Physac/meson.build deleted file mode 100644 index 895a293..0000000 --- a/examples/Physac/meson.build +++ /dev/null @@ -1,7 +0,0 @@ -executable ( - 'application', - - 'Main.vala', - - dependencies: project_dependency -) diff --git a/examples/SmoothPixel/Main.vala b/examples/SmoothPixel/Main.vala deleted file mode 100644 index 82ef631..0000000 --- a/examples/SmoothPixel/Main.vala +++ /dev/null @@ -1,86 +0,0 @@ -using Raylib; - -public const int SCREEN_WIDTH = 800; -public const int SCREEN_HEIGHT = 450; - -public const int VIRTUAL_SCREEN_WIDTH = 160; -public const int VIRTUAL_SCREEN_HEIGHT = 90; - -const float VIRTUAL_RATIO = (float)SCREEN_WIDTH / (float)VIRTUAL_SCREEN_WIDTH; - -public static int main () { - init_window (SCREEN_WIDTH, SCREEN_HEIGHT, "raylib [core] example - smooth pixel-perfect camera"); - - Camera2D world_space_camera = { }; - world_space_camera.zoom = 1.0f; - - Camera2D screen_space_camera = { }; - screen_space_camera.zoom = 1.0f; - - RenderTexture2D target = load_render_texture (VIRTUAL_SCREEN_WIDTH, VIRTUAL_SCREEN_HEIGHT); - - Rectangle rec01 = { 70.0f, 35.0f, 20.0f, 20.0f }; - Rectangle rec02 = { 90.0f, 55.0f, 30.0f, 10.0f }; - Rectangle rec03 = { 80.0f, 65.0f, 15.0f, 25.0f }; - - Rectangle source_rectangle = { 0.0f, 0.0f, target.texture.width, -target.texture.height }; - Rectangle destination_rectangle = { -VIRTUAL_RATIO, -VIRTUAL_RATIO, SCREEN_WIDTH + (VIRTUAL_RATIO * 2), SCREEN_HEIGHT + (VIRTUAL_RATIO * 2) }; - - Vector2 origin = { 0.0f, 0.0f }; - - float rotation = 0.0f; - float time = 0.0f; - - float camera_x = 0.0f; - float camera_y = 0.0f; - - set_target_fps (60); - - // Main game loop - while (!window_should_close ()) { - rotation += 60.0f * get_frame_time (); - - time = (float)get_time (); - - camera_x = (sinf (time) * 50.0f) - 10.0f; - camera_y = cosf (time) * 30.0f; - - screen_space_camera.target = { camera_x, camera_y }; - - world_space_camera.target.x = (int)screen_space_camera.target.x; - screen_space_camera.target.x -= world_space_camera.target.x; - screen_space_camera.target.x *= VIRTUAL_RATIO; - - world_space_camera.target.y = (int)screen_space_camera.target.y; - screen_space_camera.target.y -= world_space_camera.target.y; - screen_space_camera.target.y *= VIRTUAL_RATIO; - - begin_texture_mode (target); - clear_background (RAYWHITE); - - begin_mode_2D (world_space_camera); - draw_rectangle_pro (rec01, origin, rotation, BLACK); - draw_rectangle_pro (rec02, origin, -rotation, RED); - draw_rectangle_pro (rec03, origin, rotation + 45.0f, BLUE); - end_mode_2D (); - end_texture_mode(); - - begin_drawing (); - clear_background (RED); - - begin_mode_2D (screen_space_camera); - draw_texture_pro (target.texture, source_rectangle, destination_rectangle, origin, 0.0f, WHITE); - end_mode_2D (); - - draw_text (@"Screen resolution: $(SCREEN_WIDTH)x$(SCREEN_HEIGHT)", 10, 10, 20, DARKBLUE); - draw_text (@"World resolution: $(VIRTUAL_SCREEN_WIDTH)x$(VIRTUAL_SCREEN_HEIGHT)", 10, 40, 20, DARKGREEN); - draw_fps ( get_screen_width () - 95, 10); - end_drawing (); - } - - unload_render_texture (target); - - close_window (); - - return 0; -} diff --git a/examples/SmoothPixel/meson.build b/examples/SmoothPixel/meson.build deleted file mode 100644 index 895a293..0000000 --- a/examples/SmoothPixel/meson.build +++ /dev/null @@ -1,7 +0,0 @@ -executable ( - 'application', - - 'Main.vala', - - dependencies: project_dependency -) diff --git a/meson.build b/meson.build index 74b4ed5..369e901 100644 --- a/meson.build +++ b/meson.build @@ -1,8 +1,13 @@ -project ('Raylib-vala', [ 'vala', 'c' ], version: '4.2') - +project ( + 'Raylib-vala', + 'vala', 'c', + version: '5.0.0', +) +pkg = import('pkgconfig') # Variables source_dir = meson.current_source_dir () vapi_dir = source_dir / 'vapi' +version = meson.project_version() # Build variables project_dependency = [] @@ -14,25 +19,105 @@ cc = meson.get_compiler ('c') # Compiler arguments valac_arguments = [ '--vapidir', vapi_dir, - '--profile=posix' + '--debug', ] cc_arguments = [ '-DPHYSAC_IMPLEMENTATION' ] +# Debug stuff. +# Doing this because the debug defaults for Meson are really bad. +# More debug symbols. +if cc.has_argument('-g3') == true + cc_arguments += '-g3' +elif cc.has_argument('-g') == true + cc_arguments += '-g' +endif +# Compress debug symbols if possible. +if cc.has_link_argument('-Wl,--compress-debug-sections=zstd') == true + add_project_link_arguments( + '-Wl,--compress-debug-sections=zstd', + language: 'c' + ) +elif cc.has_link_argument('-Wl,--compress-debug-sections=zlib') == true + add_project_link_arguments( + '-Wl,--compress-debug-sections=zlib', + language: 'c' + ) +endif + +# Fixes error with lambda's on Clang (Maybe windows specific?) +if cc.has_argument('-Wno-incompatible-function-pointer-types') == true + cc_arguments += '-Wno-incompatible-function-pointer-types' +endif + +# Disables/Cleans up some warnings that vala produces. Possibly an issue with GCC 13 only? +if cc.has_argument('-Wno-incompatible-pointer-types') == true + cc_arguments += '-Wno-incompatible-pointer-types' +endif +if cc.has_argument('-Wno-deprecated-declarations') == true + cc_arguments += '-Wno-deprecated-declarations' +endif +if cc.has_argument('-Wno-unused-function') == true + cc_arguments += '-Wno-unused-function' +endif +if cc.has_argument('-Wno-unused-variable') == true + cc_arguments += '-Wno-unused-variable' +endif +if cc.has_argument('-Wno-discarded-qualifiers') == true + cc_arguments += '-Wno-discarded-qualifiers' +endif +if cc.has_argument('-Wno-unused-but-set-variable') == true + cc_arguments += '-Wno-unused-but-set-variable' +endif +if cc.has_argument('-Wno-dangling-pointer') == true + cc_arguments += '-Wno-dangling-pointer' +endif + add_project_arguments (valac_arguments, language: 'vala') add_project_arguments (cc_arguments, language: 'c') -project_dependency = [ - valac.find_library ('raylib', dirs: vapi_dir), - valac.find_library ('rlgl', dirs: vapi_dir), - valac.find_library ('physac', dirs: vapi_dir), +glib_dep = dependency('glib-2.0') +gobject_dep = dependency('gobject-2.0') +gio_dep = dependency('gio-2.0') - cc.find_library ('raylib'), - cc.find_library ('m') +project_dependency = [ + glib_dep, + gobject_dep, + gio_dep, + dependency('raylib', fallback: ['raylib', 'raylib_dep']), + valac.find_library('raylib', required: true, dirs: vapi_dir), + #valac.find_library ('rlgl', dirs: vapi_dir), + #valac.find_library ('physac', dirs: vapi_dir), + cc.find_library ('m', required: false) # Only neccesary of systems where math *isn't* in the C Library. ] -subdir ('examples/Camera3D') -subdir ('examples/SmoothPixel') -subdir ('examples/Physac') +# Raylib OOP Library Sources +subdir('src/lib') + +# Raylib OOP Library +raylib_oop_lib = shared_library( + 'raylib_oop', + sources: raylib_oop_src, + dependencies: project_dependency, + install: true, + vala_args: ['--vapi-comments'], + version: version, + install_dir: [true, true, true], +) + +# pkgconfig +pkg.generate( + raylib_oop_lib, + description: 'OOP Binding of Raylib for Vala.', + requires: ['raylib'], +) + +raylib_oop_dep = declare_dependency( + link_with: raylib_oop_lib, + dependencies: project_dependency, + include_directories: ['.'] +) + +subdir('src/examples') \ No newline at end of file diff --git a/meson_options.txt b/meson_options.txt new file mode 100644 index 0000000..45cd20e --- /dev/null +++ b/meson_options.txt @@ -0,0 +1,6 @@ +option( + 'examples', + type: 'boolean', + value: true, + description: 'Build the Test Applications.' +) diff --git a/src/examples/core/core_2d_camera.vala b/src/examples/core/core_2d_camera.vala new file mode 100644 index 0000000..e555c0a --- /dev/null +++ b/src/examples/core/core_2d_camera.vala @@ -0,0 +1,213 @@ +/* + * Copyright 2024 Charadon + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using GLib; +using RaylibOOP; +using RaylibOOP.Shapes; +using RaylibOOP.Input; + +public class Game : GLib.Application { + private Window window; + private MainLoop loop; + private TimeoutSource timeout; + /* Resolution */ + private const int screenWidth = 800; + private const int screenHeight = 450; + + private const int MAX_BUILDINGS = 100; + public int spacing = 0; + private Rectangle player; + private Rectangle ground; + private 2DCamera camera; + + private class building { + public Rectangle shape; + public Color color; + public building(int spacing) { + shape = new Rectangle(1, 1, 1, 1); + this.shape.width = (float)Random.int_range(50, 200); + this.shape.height = (float)Random.int_range(100, 800); + this.shape.y = screenHeight - 130.0f - this.shape.height; + this.shape.x = -6000.0f + spacing; + + this.color = new Color.from_rgba( + (uint8)Random.int_range(200, 240), + (uint8)Random.int_range(200, 240), + (uint8)Random.int_range(200, 250), + 255 + ); + } + } + Array buildings; + + private Game() { + /* GLib.Application properties. Set the application to a reverse DNS. If + * your game is named Pong, and your website is cool.site. Then the' + * application_id would be: site.cool.Pong */ + Object ( + application_id: "io.github.lxmcf.RaylibOOP.core_2d_camera", + flags: ApplicationFlags.FLAGS_NONE + ); + } + + ~Game() { + window = null; + } + + private bool main_loop() { + /* Check if Application Should Close */ + if(window.should_close) { + /* Tell loop to stop */ + loop.quit(); + return(false); + } + /* Player controls */ + if(Keyboard.is_down(Keyboard.Key.RIGHT)) { + player.x += 2; + } else if(Keyboard.is_down(Keyboard.Key.LEFT)) { + player.x -= 2; + } + /* Update camera */ + + /* Update camera with player's position. */ + camera.target = new Vector2(player.x+20, player.y+20); + + /* Rotate camera controls */ + if(Keyboard.is_down(Keyboard.Key.A)) { + camera.rotation--; + } else if(Keyboard.is_down(Keyboard.Key.S)) { + camera.rotation++; + } + + /* Camera zoom controls */ + camera.zoom += ((float)Mouse.wheel_move.y*0.05f); + if(camera.zoom > 3.0f) { + camera.zoom = 3.0f; + } else if(camera.zoom < 0.1f) { + camera.zoom = 0.1f; + } + + /* Reset camera controls */ + if(Keyboard.is_down(Keyboard.Key.R)) { + camera.zoom = 1.0f; + camera.rotation = 0.0f; + } + + window.draw(()=>{ + window.clear_background(RaylibOOP.Color.RAY_WHITE); + /* Draw the things that move with the camera */ + camera.draw(()=>{ + ground.draw(Color.DARK_GRAY, null, null); + foreach (var b in buildings) { + b.shape.draw(b.color, null, null); + } + player.draw(Color.RED, null, null); + Line.draw( + new Vector2(camera.target.x, -screenHeight*10), + new Vector2(camera.target.x, screenHeight*10), + Color.GREEN + ); + Line.draw( + new Vector2(-screenWidth*10, camera.target.y), + new Vector2(screenWidth*10, camera.target.y), + Color.GREEN + ); + }); + /* Draw screen box */ + Font.DEFAULT.draw_text("SCREEN AREA", new Vector2(640,10), 20, null, Color.RED); + new Rectangle(0, 0, screenWidth, screenHeight).draw_outline(5, Color.RED); + var controlBox = new Rectangle(10, 10, 250, 113); + /* Draw box that shows controls */ + controlBox.draw(Color.fade(Color.SKY_BLUE, 0.5f), null, null); + controlBox.draw_outline(1, Color.BLUE); + Font.DEFAULT.draw_text("Free 2d camera controls", new Vector2(20,20), 10, null, Color.BLACK); + Font.DEFAULT.draw_text("- Right/Left to move Offset", new Vector2(40,40), 10, null, Color.DARK_GRAY); + Font.DEFAULT.draw_text("- Mouse Wheel to Zoom in-out", new Vector2(40,60), 10, null, Color.DARK_GRAY); + Font.DEFAULT.draw_text("- A / S to Rotate", new Vector2(40,80), 10, null, Color.DARK_GRAY); + Font.DEFAULT.draw_text("- R to reset Zoom and Rotation", new Vector2(40,100), 10, null, Color.DARK_GRAY); + }); + /* Tell Loop to keep going */ + return(true); + } + + /* Handle Command Line Args */ + public override int handle_local_options(VariantDict args) { + /* Print Version and Exit */ + if(args.contains("version")) { + stdout.printf(VERSION); + Process.exit(0); + } + /* Print License and Exit */ + if(args.contains("license")) { + stdout.printf(LICENSE); + Process.exit(0); + } + /* Run Application */ + return(-1); + } + + public override void activate() { + + /* Create Window */ + try { + /* Set the title to the application_id to begin with, so Wayland-based + * compositors can figure out their name. Not *technically* needed but + * com.example.Example is easier to make rules for than "COOL GAME WINDOW TITLE" */ + window = new Window(screenWidth, screenHeight, this.application_id); + } catch(WindowError e) { + error(e.message); + } + window.title = "RaylibOOP - Core 2D Example"; + /* Create GLib MainLoop */ + loop = new MainLoop(); + timeout = new TimeoutSource(1); + timeout.set_callback(this.main_loop); + timeout.attach(loop.get_context()); + + /* Create buildings */ + buildings = new Array(); + for(int i = 0; i < MAX_BUILDINGS; ++i) { + buildings.append_val(new building(spacing)); + spacing += (int)buildings.index(i).shape.width; + } + + /* Initialize player */ + player = new Rectangle(400, 280, 40, 40); + /* Initalize camera */ + camera = new 2DCamera( + new Vector2(screenWidth/2.0f, screenHeight/2.0f), + new Vector2(player.x+20.0f, player.y+20.0f), + 0.0f, + 1.0f + ); + /* Create ground */ + ground = new Rectangle( + -6000, 320, 13000, 8000 + ); + /* Run Main Loop */ + loop.run(); + } + + public static int main(string[] args) { + /* Create GLib.Application */ + var app = new Game(); + /* Add Command Line Options */ + app.add_main_option("version", 'v', GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "Displays program's version.", null); + app.add_main_option("license", 'l', GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "Displays program's license.", null); + /* Run Application */ + app.run(args); + return(0); + } +} diff --git a/src/examples/core/core_basic_screen_manager.vala b/src/examples/core/core_basic_screen_manager.vala new file mode 100644 index 0000000..f61ace1 --- /dev/null +++ b/src/examples/core/core_basic_screen_manager.vala @@ -0,0 +1,165 @@ +/* + * Copyright 2024 Charadon + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using GLib; +using RaylibOOP; +using RaylibOOP.Input; +using RaylibOOP.Shapes; + +public class Game : GLib.Application { + private Window window; + private MainLoop loop; + private TimeoutSource timeout; + + private int framesCounter = 0; /* To later figure out if 2 seconds has passed. */ + private enum GameScreen { + LOGO = 0, + TITLE = 1, + GAMEPLAY = 2, + ENDING = 3, + } + private int currentScreen = GameScreen.LOGO; + + private Game() { + Object ( + application_id: "io.github.lxmcf.RaylibOOP.core_basic_screen_manager", + flags: ApplicationFlags.FLAGS_NONE + ); + } + + ~Game() { + window = null; + } + + private bool main_loop() { + /* Check if Application Should Close */ + if(window.should_close) { + /* Tell loop to stop */ + loop.quit(); + return(false); + } + + /* Change Screen */ + switch(currentScreen) { + case GameScreen.LOGO: { + this.framesCounter++; + if(this.framesCounter > 120) { + currentScreen = GameScreen.TITLE; + } + break; + } + case GameScreen.TITLE: { + if(Keyboard.is_pressed(Keyboard.Key.ENTER) || Touch.is_gesture_detected(Touch.Gestures.TAP)) { + currentScreen = GameScreen.GAMEPLAY; + } + break; + } + case GameScreen.GAMEPLAY: { + if(Keyboard.is_pressed(Keyboard.Key.ENTER) || Touch.is_gesture_detected(Touch.Gestures.TAP)) { + currentScreen = GameScreen.ENDING; + } + break; + } + case GameScreen.ENDING: { + if(Keyboard.is_pressed(Keyboard.Key.ENTER) || Touch.is_gesture_detected(Touch.Gestures.TAP)) { + currentScreen = GameScreen.TITLE; + } + break; + } + } + + window.draw(()=>{ + window.clear_background(RaylibOOP.Color.RAY_WHITE); + /* Draw Current Screen */ + var screenRectangle = new Rectangle(0, 0, window.width, window.height); + switch(currentScreen) { + case GameScreen.LOGO: { + Font.DEFAULT.draw_text("LOGO SCREEN", new Vector2(20, 20), 40, null, Color.LIGHT_GRAY); + Font.DEFAULT.draw_text("WAIT for 2 SECONDS...", new Vector2(290, 220), 20, null, Color.GRAY); + break; + } + case GameScreen.TITLE: { + screenRectangle.draw(Color.GREEN, null, null); + Font.DEFAULT.draw_text("TITLE SCREEN", new Vector2(20, 20), 40, null, Color.DARK_GREEN); + Font.DEFAULT.draw_text("PRESS ENTER or TAP to JUMP to GAMEPLAY SCREEN", new Vector2(120, 220), 20, null, Color.DARK_GREEN); + break; + } + case GameScreen.GAMEPLAY: { + screenRectangle.draw(Color.PURPLE, null, null); + Font.DEFAULT.draw_text("GAMEPLAY SCREEN", new Vector2(20, 20), 40, null, Color.MAROON); + Font.DEFAULT.draw_text("PRESS ENTER or TAP to JUMP to ENDING SCREEN", new Vector2(130, 220), 20, null, Color.MAROON); + break; + } + case GameScreen.ENDING: { + screenRectangle.draw(Color.BLUE, null, null); + Font.DEFAULT.draw_text("ENDING SCREEN", new Vector2(20, 20), 40, null, Color.DARK_BLUE); + Font.DEFAULT.draw_text("PRESS ENTER or TAP to RETURN to TITLE SCREEN", new Vector2(120, 220), 20, null, Color.DARK_BLUE); + break; + } + } + }); + /* Tell Loop to keep going */ + return(true); + } + + /* Handle Command Line Args */ + public override int handle_local_options(VariantDict args) { + /* Print Version and Exit */ + if(args.contains("version")) { + stdout.printf(VERSION); + Process.exit(0); + } + /* Print License and Exit */ + if(args.contains("license")) { + stdout.printf(LICENSE); + Process.exit(0); + } + /* Run Application */ + return(-1); + } + + public override void activate() { + const int screenWidth = 800; + const int screenHeight = 450; + /* Create Window */ + try { + /* Set the title to the application_id to begin with, so Wayland-based + * compositors can figure out their name. Not *technically* needed but + * com.example.Example is easier to make rules for than "COOL GAME WINDOW TITLE" */ + window = new Window(screenWidth, screenHeight, this.application_id); + } catch(WindowError e) { + error(e.message); + } + window.title = "RaylibOOP - core_basic_screen_manager"; + /* Create GLib MainLoop */ + loop = new MainLoop(); + timeout = new TimeoutSource(1); + timeout.set_callback(this.main_loop); + timeout.attach(loop.get_context()); + /* Run Main Loop */ + loop.run(); + } + + public static int main(string[] args) { + /* Create GLib.Application */ + var app = new Game(); + /* Add Command Line Options */ + app.add_main_option("version", 'v', GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "Displays program's version.", null); + app.add_main_option("license", 'l', GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "Displays program's license.", null); + /* Run Application */ + app.run(args); + return(0); + } +} diff --git a/src/examples/core/core_basic_window.vala b/src/examples/core/core_basic_window.vala new file mode 100644 index 0000000..84c4b64 --- /dev/null +++ b/src/examples/core/core_basic_window.vala @@ -0,0 +1,99 @@ +/* + * Copyright 2024 Charadon + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using GLib; +using RaylibOOP; + +public class BasicWindow : Application { + private Window window; + private MainLoop loop; + private TimeoutSource timeout; + + private BasicWindow() { + Object ( + application_id: "io.github.lxmcf.RaylibOOP.core_basic_window", + flags: ApplicationFlags.FLAGS_NONE + ); + } + + ~BasicWindow() { + window = null; + } + + private bool main_loop() { + /* Check if Application Should Close */ + if(window.should_close) { + /* Tell loop to stop */ + loop.quit(); + return(false); + } + /* Draw Frames */ + window.draw(()=>{ + window.clear_background(Color.RAY_WHITE); + Font.DEFAULT.draw_text( + "Congrats! You created your first window!", + new Shapes.Vector2(190, 200), 20, null, Color.LIGHT_GRAY + ); + window.draw_fps(0, 0); + }); + /* Tell Loop to keep going */ + return(true); + } + + public override int handle_local_options(VariantDict args) { + /* Print Version and Exit */ + if(args.contains("version")) { + stdout.printf(VERSION); + Process.exit(0); + } + if(args.contains("license")) { + stdout.printf(LICENSE); + Process.exit(0); + } + /* Activate Application */ + return(-1); + } + + public override void activate() { + const int screenWidth = 800; + const int screenHeight = 450; + /* Create Window */ + try { + window = new Window(screenWidth, screenHeight, "RaylibOOP [core] example - basic window"); + } catch(WindowError e) { + error(e.message); + } + /* Create GLib MainLoop */ + loop = new MainLoop(); + timeout = new TimeoutSource(1); + timeout.set_callback(this.main_loop); + timeout.attach(loop.get_context()); + /* Run Main Loop */ + loop.run(); + } + + public static int main(string[] args) { + /* Force Logs to Show */ + Environment.set_variable("G_MESSAGES_DEBUG", "all", true); + /* Create GLib.Application */ + var app = new BasicWindow(); + /* Handle Args */ + app.add_main_option("version", 'v', GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "Displays program's version.", null); + app.add_main_option("license", 'l', GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "Displays program's license.", null); + /* Run Application */ + app.run(args); + return(0); + } +} diff --git a/src/examples/meson.build b/src/examples/meson.build new file mode 100644 index 0000000..12ef1bf --- /dev/null +++ b/src/examples/meson.build @@ -0,0 +1,44 @@ +# Examples +if get_option('examples') == true + executable( + 'core_basic_window', + dependencies: [raylib_oop_dep], + sources: [ + 'core/core_basic_window.vala', + 'meta/license.vala', + 'meta/version.vala', + ], + ) + executable( + 'core_basic_screen_manager', + dependencies: [raylib_oop_dep], + sources: [ + 'core/core_basic_screen_manager.vala', + 'meta/license.vala', + 'meta/version.vala', + ], + ) + executable( + 'template', + dependencies: [raylib_oop_dep], + sources: [ + 'template.vala', + ], + ) + executable( + 'draw_line', + dependencies: [raylib_oop_dep], + sources: [ + 'misc/draw_line.vala', + ], + ) + executable( + 'core_2d_camera', + dependencies: [raylib_oop_dep], + sources: [ + 'core/core_2d_camera.vala', + 'meta/license.vala', + 'meta/version.vala', + ], + ) +endif diff --git a/src/examples/meta/license.vala b/src/examples/meta/license.vala new file mode 100644 index 0000000..894d792 --- /dev/null +++ b/src/examples/meta/license.vala @@ -0,0 +1,15 @@ +const string LICENSE = """Copyright 2024 Charadon + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +"""; diff --git a/src/examples/meta/version.vala b/src/examples/meta/version.vala new file mode 100644 index 0000000..935c917 --- /dev/null +++ b/src/examples/meta/version.vala @@ -0,0 +1 @@ +const string VERSION = "v5.0.0"; \ No newline at end of file diff --git a/src/examples/misc/draw_line.vala b/src/examples/misc/draw_line.vala new file mode 100644 index 0000000..4f6a33a --- /dev/null +++ b/src/examples/misc/draw_line.vala @@ -0,0 +1,35 @@ +/* + * Copyright 2024 Charadon + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* To make sure lines work. */ +using GLib; +using RaylibOOP; +using RaylibOOP.Shapes; + +int main(string[] args) { + Window window; + try { + window = new Window(640, 480, "Draw Line Test"); + } catch(WindowError e) { + error(e.message); + } + while(window.should_close == false) { + window.draw(()=>{ + Line.draw_strip({new Vector2(0,0), new Vector2(550,55), new Vector2(220, 640)}, Color.RED); + }); + } + return(0); +} \ No newline at end of file diff --git a/src/examples/template.vala b/src/examples/template.vala new file mode 100644 index 0000000..37dc114 --- /dev/null +++ b/src/examples/template.vala @@ -0,0 +1,101 @@ +/* + * RaylibOOP Template by Charadon + * + * To the extent possible under law, the person who associated CC0 with + * RaylibOOP Template has waived all copyright and related or neighboring rights + * to RaylibOOP Template. + * + * You should have received a copy of the CC0 legalcode along with this + * work. If not, see . + */ +using GLib; +using RaylibOOP; + +const string VERSION = "VERSION HERE\n"; +const string LICENSE = """ +LICENSE GOES HERE +"""; + +public class Game : GLib.Application { + private Window window; + private MainLoop loop; + private TimeoutSource timeout; + + private Game() { + /* GLib.Application properties. Set the application to a reverse DNS. If + * your game is named Pong, and your website is cool.site. Then the' + * application_id would be: site.cool.Pong */ + Object ( + application_id: "com.example.GAME_NAME_HERE", + flags: ApplicationFlags.FLAGS_NONE + ); + } + + ~Game() { + window = null; + } + + private bool main_loop() { + /* Check if Application Should Close */ + if(window.should_close) { + /* Tell loop to stop */ + loop.quit(); + return(false); + } + window.draw(()=>{ + window.clear_background(RaylibOOP.Color.WHITE); + /* CODE GOES HERE */ + }); + /* Tell Loop to keep going */ + return(true); + } + + /* Handle Command Line Args */ + public override int handle_local_options(VariantDict args) { + /* Print Version and Exit */ + if(args.contains("version")) { + stdout.printf(VERSION); + Process.exit(0); + } + /* Print License and Exit */ + if(args.contains("license")) { + stdout.printf(LICENSE); + Process.exit(0); + } + /* Run Application */ + return(-1); + } + + public override void activate() { + const int screenWidth = 800; + const int screenHeight = 450; + /* Create Window */ + try { + /* Set the title to the application_id to begin with, so Wayland-based + * compositors can figure out their name. Not *technically* needed but + * com.example.Example is easier to make rules for than "COOL GAME WINDOW TITLE" */ + window = new Window(screenWidth, screenHeight, this.application_id); + } catch(WindowError e) { + error(e.message); + } + window.title = "RaylibOOP - Template"; + /* Create GLib MainLoop */ + loop = new MainLoop(); + timeout = new TimeoutSource(1); + timeout.set_callback(this.main_loop); + timeout.attach(loop.get_context()); + /* Run Main Loop */ + loop.run(); + } + + public static int main(string[] args) { + /* Create GLib.Application */ + var app = new Game(); + /* Add Command Line Options */ + app.add_main_option("version", 'v', GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "Displays program's version.", null); + app.add_main_option("license", 'l', GLib.OptionFlags.NONE, GLib.OptionArg.NONE, "Displays program's license.", null); + /* Run Application */ + app.run(args); + return(0); + } +} diff --git a/src/lib/2DCamera.vala b/src/lib/2DCamera.vala new file mode 100644 index 0000000..aaa12c2 --- /dev/null +++ b/src/lib/2DCamera.vala @@ -0,0 +1,83 @@ +using GLib; +using RaylibOOP.Shapes; + +namespace RaylibOOP { + public class 2DCamera : Object { + internal Raylib.Camera2D iCamera; + /* Constructors */ + public 2DCamera(Vector2 offset, Vector2 target, float rotation, float zoom) { + iCamera.offset = offset.iVector; + iCamera.target = target.iVector; + iCamera.rotation = rotation; + iCamera.zoom = zoom; + } + /* Methods */ + /** + * Begin 2D mode with camera + */ + public void begin_draw() { + Raylib.begin_mode_2D(this.iCamera); + return; + } + /** + * Ends 2D mode with camera + */ + public void end_draw() { + Raylib.end_mode_2D(); + } + /** + * Draw in 2D Mode. + */ + public void draw(Func func) { + this.begin_draw(); + func(null); + this.end_draw(); + } + + /* Properties */ + /** + * Offset of the camera + */ + public Vector2 offset { + owned get { + return(new Vector2(this.iCamera.offset.x, this.iCamera.offset.y)); + } + set { + this.iCamera.offset = value.iVector; + } + } + /** + * Target of the camera. + */ + public Vector2 target { + owned get { + return(new Vector2(this.iCamera.target.x, this.iCamera.target.y)); + } + set { + this.iCamera.target = value.iVector; + } + } + /** + * Zoom of the camera. + */ + public float zoom { + get { + return(this.iCamera.zoom); + } + set { + this.iCamera.zoom = value; + } + } + /** + * Rotation of the camera. + */ + public float rotation { + get { + return(this.iCamera.rotation); + } + set { + this.iCamera.rotation = value; + } + } + } +} \ No newline at end of file diff --git a/src/lib/Audio/Music.vala b/src/lib/Audio/Music.vala new file mode 100644 index 0000000..a459ab7 --- /dev/null +++ b/src/lib/Audio/Music.vala @@ -0,0 +1,136 @@ +using Raylib; +namespace RaylibOOP { + namespace Audio { + public class Music : GLib.Object { + /* Variables */ + private Raylib.Music iMusic; + private bool isPaused = false; + private float trackVolume = 1.0f; + private float trackPitch = 1.0f; + private float trackPan = 0.5f; + /* Constructors */ + /** + * Loads the track from a file. + */ + public Music(string file) { + if(is_audio_device_ready() == false) { + init_audio_device(); + } + this.iMusic = load_music_stream(file); + } + /** + * Loads the track from memory. + */ + public Music.from_memory(uint8[] data, string fileType) { + if(is_audio_device_ready() == false) { + init_audio_device(); + } + this.iMusic = load_music_stream_from_memory(fileType, data); + } + /* Destroyer */ + ~Music() { + unload_music_stream(this.iMusic); + } + /* Methods */ + /** + * Updates buffers for music streaming + */ + public void update() { + update_music_stream(this.iMusic); + } + /* Properties */ + /** + * If music stream is playing or stopped + */ + public bool playing { + get { + return(is_music_stream_playing(this.iMusic)); + } + set { + if(value == true) { + play_music_stream(this.iMusic); + } else { + stop_music_stream(this.iMusic); + } + } + } + /** + * If music stream is paused + */ + public bool paused { + get { + return(this.isPaused); + } + set { + if(value == true) { + isPaused = true; + pause_music_stream(this.iMusic); + } else { + isPaused = false; + resume_music_stream(this.iMusic); + } + } + } + /** + * Pan for music stream. 0.5 is center. + */ + public float pan { + get { + return(this.trackPan); + } + set { + this.trackPan = value; + set_music_pan(this.iMusic, value); + } + } + /** + * Pitch of the music stream. 1.0 if base level. + */ + public float pitch { + get { + return(this.trackPitch); + } + set { + this.trackPitch = value; + set_music_pitch(this.iMusic, value); + } + } + /** + * Volume of the music stream. 1.0 is max level. + */ + public float volume { + get { + return(this.trackVolume); + } + set { + /* No need to error out the program if an invalid value + * is given, we'll just round it up or down. */ + float f = value; + if(f > 1.0f) { + f = 1.0f; + } else if(f < 0.0f) { + f = 0.0f; + } + set_music_volume(this.iMusic, f); + this.trackVolume = f; + } + } + /** + * How long the music stream's track is. + */ + public float timeLength { + get { + return(get_music_time_length(this.iMusic)); + } + } + /** + * How far into the track the music stream is. + */ + public float timePlayed { + get { + return(get_music_time_played(this.iMusic)); + } + } + } + } +} diff --git a/src/lib/Audio/Sound.vala b/src/lib/Audio/Sound.vala new file mode 100644 index 0000000..286a0e1 --- /dev/null +++ b/src/lib/Audio/Sound.vala @@ -0,0 +1,151 @@ +namespace RaylibOOP { + namespace Audio { + public class Sound : GLib.Object { + /* Variables */ + private Raylib.Sound iSound; + private bool isPaused = false; + private float soundVolume = 1.0f; + private float soundPitch = 1.0f; + private float soundPan = 0.5f; + /* Constructors */ + /** + * Load sound from a file. + */ + Sound(string file) { + if(Raylib.is_audio_device_ready() == false) { + Raylib.init_audio_device(); + } + this.iSound = Raylib.load_sound(file); + } + /** + * Load sound from memory + */ + Sound.from_memory(uint8[] bytes, string fileType) { + if(Raylib.is_audio_device_ready() == false) { + Raylib.init_audio_device(); + } + Raylib.Wave wave = Raylib.load_wave_from_memory(fileType, bytes); + this.iSound = Raylib.load_sound_from_wave(wave); + Raylib.unload_wave(wave); + } + /** + * Create a new sound that shares the same sample data as the source sound, does not own the sound data + */ + Sound.from_alias(Raylib.Sound source) { + if(Raylib.is_audio_device_ready() == false) { + Raylib.init_audio_device(); + } + this.iSound = Raylib.load_sound_alias(source); + } + /** + * Load sound from wave + */ + Sound.from_wave(Raylib.Wave wave) { + if(Raylib.is_audio_device_ready() == false) { + Raylib.init_audio_device(); + } + this.iSound = Raylib.load_sound_from_wave(wave); + } + /* Destroyer */ + ~Sound() { + Raylib.unload_sound(this.iSound); + } + /* Methods */ + /** + * Update sound buffer with new data + */ + public void update(void* data, int sampleCount) { + Raylib.update_sound(this.iSound, data, sampleCount); + } + /* Properties */ + /** + * If sound is playing. + */ + public bool playing { + get { + return(Raylib.is_sound_playing(this.iSound)); + } + set { + if(value == true) { + Raylib.play_sound(this.iSound); + isPaused = false; + } else { + Raylib.stop_sound(this.iSound); + } + + } + } + /** + * If sound is paused + */ + public bool paused { + get { + return(this.isPaused); + } + set { + if(value == true) { + Raylib.pause_sound(this.iSound); + isPaused = true; + } else { + Raylib.resume_sound(this.iSound); + isPaused = false; + } + } + } + /** + * Volume of sound. + */ + public float volume { + get { + return(this.soundVolume); + } + set { + float volume = value; + if(volume > 1.0f) { + volume = 1.0f; + } else if(volume < 0.0f) { + volume = 0.0f; + } + Raylib.set_sound_volume(this.iSound, volume); + this.soundVolume = volume; + } + } + /** + * Pitch of sound. + */ + public float pitch { + get { + return(this.soundPitch); + } + set { + float pitch = value; + if(pitch > 1.0f) { + pitch = 1.0f; + } else if(pitch < 0.0f) { + pitch = 0.0f; + } + Raylib.set_sound_pitch(this.iSound, pitch); + this.soundPitch = pitch; + } + } + /** + * Pan of sound. + */ + public float pan { + get { + return(this.soundPan); + } + set { + float pan = value; + if(pan > 1.0f) { + pan = 1.0f; + } else if(pan < 0.0f) { + pan = 0.0f; + } + Raylib.set_sound_pan(this.iSound, pan); + this.soundPan = pan; + } + } + } + } +} diff --git a/src/lib/Audio/Types.vala b/src/lib/Audio/Types.vala new file mode 100644 index 0000000..0c13619 --- /dev/null +++ b/src/lib/Audio/Types.vala @@ -0,0 +1,17 @@ +using Raylib; +namespace RaylibOOP { + namespace Audio { + /** + * File Types for use with loading audio data from memory. + */ + namespace FileType { + public const string WAV = ".wav"; + public const string OGG = ".ogg"; + public const string MP3 = ".mp3"; + public const string QOA = ".qoa"; + public const string FLAC = ".flac"; + public const string XM = ".xm"; + public const string MOD = ".mod"; + } + } +} diff --git a/src/lib/Automation/EventList.vala b/src/lib/Automation/EventList.vala new file mode 100644 index 0000000..25d20eb --- /dev/null +++ b/src/lib/Automation/EventList.vala @@ -0,0 +1,46 @@ +namespace RaylibOOP { + namespace Automation { + public class EventList : GLib.Object { + /* Variables */ + internal Raylib.AutomationEventList eventList; + /* Constructors */ + public EventList(string file) { + eventList = Raylib.load_automation_event_list(file); + return; + } + ~EventList() { + Raylib.unload_automation_event_list(&eventList); + } + /* Methods */ + public void export(string exportFile) throws GLib.FileError { + if(Raylib.export_automation_event_list(this.eventList, exportFile) == false) { + throw new GLib.FileError.FAILED(@"Failed to create file: "+GLib.strerror(GLib.errno)); + } + return; + } + /** + * Events entries + */ + public Raylib.AutomationEvent get_event(uint index) { + return(this.eventList.events[index]); + } + /* Properties */ + /** + * Events max entries. + */ + public uint capacity { + get { + return(this.eventList.capacity); + } + } + /** + * Events entries count + */ + public uint count { + get { + return(this.eventList.count); + } + } + } + } +} diff --git a/src/lib/Clipboard.vala b/src/lib/Clipboard.vala new file mode 100644 index 0000000..7fa2963 --- /dev/null +++ b/src/lib/Clipboard.vala @@ -0,0 +1,19 @@ +namespace RaylibOOP { + public class Clipboard { + private Clipboard() { + return; + } + /** + * Get clipboard text content + */ + public static string get() { + return(Raylib.get_clipboard_text()); + } + /** + * Set clipboard text content + */ + public static void set(string text) { + Raylib.set_clipboard_text(text); + } + } +} diff --git a/src/lib/Color.vala b/src/lib/Color.vala new file mode 100644 index 0000000..3a107f3 --- /dev/null +++ b/src/lib/Color.vala @@ -0,0 +1,226 @@ +using RaylibOOP.Util; + +namespace RaylibOOP { + public class Color : GLib.Object { + /* Variables */ + internal Raylib.Color iColor; + /* Constructors */ + /** + * Creates a color from rgba + */ + public Color.from_rgba(uint8 r, uint8 g, uint8 b, uint8 a) { + this.iColor.r = r; + this.iColor.g = g; + this.iColor.b = b; + this.iColor.a = a; + } + /** + * Creates a color from a traditional HTML rgba code. + */ + public Color.from_html_code(string rrggbbaa) { + /* Convert the HTML code to rbga and return it. */ + int index = 0; + if(rrggbbaa[0] == '#') { // Skip hashtag. + index++; + } + this.iColor.r = ((hex_to_uint8(rrggbbaa[index])*16)+hex_to_uint8(rrggbbaa[index+1])); + this.iColor.g = ((hex_to_uint8(rrggbbaa[index+2])*16)+hex_to_uint8(rrggbbaa[index+3])); + this.iColor.b = ((hex_to_uint8(rrggbbaa[index+4])*16)+hex_to_uint8(rrggbbaa[index+5])); + this.iColor.a = ((hex_to_uint8(rrggbbaa[index+6])*16)+hex_to_uint8(rrggbbaa[index+7])); + } + /** + * Creates the object from a Raylib.Color struct + */ + public Color.from_raylib_color(Raylib.Color color) { + this.iColor.r = color.r; + this.iColor.g = color.g; + this.iColor.b = color.b; + this.iColor.a = color.a; + } + /** + * Creates a faded color. + */ + public static Color fade(Color color, float alpha) { + var c = new Color.from_raylib_color(color.iColor); + c.a = (uint8)(alpha*255); + return(c); + } + /* Properties */ + /** + * Red + */ + public uint8 r { + get { + return(this.iColor.r); + } + set { + this.iColor.r = value; + } + } + /** + * Green + */ + public uint8 g { + get { + return(this.iColor.g); + } + set { + this.iColor.g = value; + } + } + /** + * Blue + */ + public uint8 b { + get { + return(this.iColor.b); + } + set { + this.iColor.b = value; + } + } + /** + * Alpha + */ + public uint8 a { + get { + return(this.iColor.a); + } + set { + this.iColor.a = value; + } + } + /* Pre-defined colors. This is awful, but I don't see another way without + * needing to use Raylib directly. Which is something I want to avoid. */ + public static Color LIGHT_GRAY { + owned get { + return(new Color.from_raylib_color(Raylib.LIGHTGRAY)); + } + } + public static Color GRAY { + owned get { + return(new Color.from_raylib_color(Raylib.GRAY)); + } + } + public static Color DARK_GRAY { + owned get { + return(new Color.from_raylib_color(Raylib.DARKGRAY)); + } + } + public static Color YELLOW { + owned get { + return(new Color.from_raylib_color(Raylib.YELLOW)); + } + } + public static Color GOLD { + owned get { + return(new Color.from_raylib_color(Raylib.GOLD)); + } + } + public static Color ORANGE { + owned get { + return(new Color.from_raylib_color(Raylib.ORANGE)); + } + } + public static Color PINK { + owned get { + return(new Color.from_raylib_color(Raylib.PINK)); + } + } + public static Color RED { + owned get { + return(new Color.from_raylib_color(Raylib.RED)); + } + } + public static Color MAROON { + owned get { + return(new Color.from_raylib_color(Raylib.MAROON)); + } + } + public static Color GREEN { + owned get { + return(new Color.from_raylib_color(Raylib.GREEN)); + } + } + public static Color LIME { + owned get { + return(new Color.from_raylib_color(Raylib.LIME)); + } + } + public static Color DARK_GREEN { + owned get { + return(new Color.from_raylib_color(Raylib.DARKGREEN)); + } + } + public static Color SKY_BLUE { + owned get { + return(new Color.from_raylib_color(Raylib.SKYBLUE)); + } + } + public static Color BLUE { + owned get { + return(new Color.from_raylib_color(Raylib.BLUE)); + } + } + public static Color DARK_BLUE { + owned get { + return(new Color.from_raylib_color(Raylib.DARKBLUE)); + } + } + public static Color PURPLE { + owned get { + return(new Color.from_raylib_color(Raylib.PURPLE)); + } + } + public static Color VIOLET { + owned get { + return(new Color.from_raylib_color(Raylib.VIOLET)); + } + } + public static Color DARK_PURPLE { + owned get { + return(new Color.from_raylib_color(Raylib.DARKPURPLE)); + } + } + public static Color BEIGE { + owned get { + return(new Color.from_raylib_color(Raylib.BEIGE)); + } + } + public static Color BROWN { + owned get { + return(new Color.from_raylib_color(Raylib.BROWN)); + } + } + public static Color DARK_BROWN { + owned get { + return(new Color.from_raylib_color(Raylib.DARKBROWN)); + } + } + public static Color WHITE { + owned get { + return(new Color.from_raylib_color(Raylib.WHITE)); + } + } + public static Color BLACK { + owned get { + return(new Color.from_raylib_color(Raylib.BLACK)); + } + } + public static Color BLANK { + owned get { + return(new Color.from_raylib_color(Raylib.BLANK)); + } + } + public static Color MAGENTA { + owned get { + return(new Color.from_raylib_color(Raylib.MAGENTA)); + } + } + public static Color RAY_WHITE { + owned get { + return(new Color.from_raylib_color(Raylib.RAYWHITE)); + } + } + } +} diff --git a/src/lib/Constants.vala b/src/lib/Constants.vala new file mode 100644 index 0000000..6d03ca6 --- /dev/null +++ b/src/lib/Constants.vala @@ -0,0 +1,5 @@ +/* Constants for OOP binding. Useful for figuring out what version of the binding your + * using, for example.. */ +namespace RaylibOOP { + const string VERSION = "v1.0.0"; +} \ No newline at end of file diff --git a/src/lib/Input/Gamepad.vala b/src/lib/Input/Gamepad.vala new file mode 100644 index 0000000..1463b20 --- /dev/null +++ b/src/lib/Input/Gamepad.vala @@ -0,0 +1,174 @@ +namespace RaylibOOP { + namespace Input { + public class Gamepad : GLib.Object { + + /* Enums */ + public enum Axis { + LEFT_X = Raylib.GamepadAxis.LEFT_X, + LEFT_Y = Raylib.GamepadAxis.LEFT_Y, + RIGHT_X = Raylib.GamepadAxis.RIGHT_X, + RIGHT_Y = Raylib.GamepadAxis.RIGHT_Y, + LEFT_TRIGGER = Raylib.GamepadAxis.LEFT_TRIGGER, + RIGHT_TRIGGER = Raylib.GamepadAxis.RIGHT_TRIGGER + } + + public enum Button { + UNKNOWN = Raylib.GamepadButton.UNKNOWN, + LEFT_FACE_UP = Raylib.GamepadButton.LEFT_FACE_UP, + LEFT_FACE_RIGHT = Raylib.GamepadButton.LEFT_FACE_RIGHT, + LEFT_FACE_DOWN = Raylib.GamepadButton.LEFT_FACE_DOWN, + LEFT_FACE_LEFT = Raylib.GamepadButton.LEFT_FACE_LEFT, + RIGHT_FACE_UP = Raylib.GamepadButton.RIGHT_FACE_UP, + RIGHT_FACE_RIGHT = Raylib.GamepadButton.RIGHT_FACE_RIGHT, + RIGHT_FACE_DOWN = Raylib.GamepadButton.RIGHT_FACE_DOWN, + RIGHT_FACE_LEFT = Raylib.GamepadButton.RIGHT_FACE_LEFT, + LEFT_TRIGGER_1 = Raylib.GamepadButton.LEFT_TRIGGER_1, + LEFT_TRIGGER_2 = Raylib.GamepadButton.LEFT_TRIGGER_2, + RIGHT_TRIGGER_1 = Raylib.GamepadButton.RIGHT_TRIGGER_1, + RIGHT_TRIGGER_2 = Raylib.GamepadButton.RIGHT_TRIGGER_2, + MIDDLE_LEFT = Raylib.GamepadButton.MIDDLE_LEFT, + MIDDLE = Raylib.GamepadButton.MIDDLE, + MIDDLE_RIGHT = Raylib.GamepadButton.MIDDLE_RIGHT, + LEFT_THUMB = Raylib.GamepadButton.LEFT_THUMB, + RIGHT_THUMB = Raylib.GamepadButton.RIGHT_THUMB + } + + /* Variables */ + internal int padID; + internal string padName; + /* Constructor */ + public Gamepad (int gamepad) throws GLib.Error { + if (Raylib.is_gamepad_available (gamepad) == false) { + throw new GLib.Error ( + GLib.Quark.from_string ("Gamepad"), + 1, + @"The gamepad specified, $(gamepad), is not available."); + } + this.padID = gamepad; + this.padName = this.name; + return; + } + + /* Methods */ + /** + * Checks if the gamepad is still available. + */ + public bool still_around () { + return (Raylib.is_gamepad_available (this.padID)); + } + + /** + * Check if a button has been pressed once. + */ + public bool is_button_pressed (Gamepad.Button button) throws GLib.Error { + if (!still_around ()) { + throw new GLib.Error ( + GLib.Quark.from_string ("Gamepad"), + 1, + @"The gamepad specified, $(this.padID):$(this.padName), is no longer available." + ); + } + return (Raylib.is_gamepad_button_pressed (this.padID, (Raylib.GamepadButton) button)); + } + + /** + * Check if a button is being pressed. + */ + public bool is_button_down (Gamepad.Button button) throws GLib.Error { + if (!still_around ()) { + throw new GLib.Error ( + GLib.Quark.from_string ("Gamepad"), + 1, + @"The gamepad specified, $(this.padID):$(this.padName), is no longer available." + ); + } + return (Raylib.is_gamepad_button_down (this.padID, (Raylib.GamepadButton) button)); + } + + /** + * Check if a button has been released once. + */ + public bool is_button_released (Gamepad.Button button) throws GLib.Error { + if (!still_around ()) { + throw new GLib.Error ( + GLib.Quark.from_string ("Gamepad"), + 1, + @"The gamepad specified, $(this.padID):$(this.padName), is no longer available." + ); + } + return (Raylib.is_gamepad_button_released (this.padID, (Raylib.GamepadButton) button)); + } + + /** + * Check if a button is NOT being pressed. + */ + public bool is_button_up (Gamepad.Button button) throws GLib.Error { + if (!still_around ()) { + throw new GLib.Error ( + GLib.Quark.from_string ("Gamepad"), + 1, + @"The gamepad specified, $(this.padID):$(this.padName), is no longer available." + ); + } + return (Raylib.is_gamepad_button_up (this.padID, (Raylib.GamepadButton) button)); + } + + /** + * Get axis movement value for an axis. + */ + public float get_axis_movement (Gamepad.Axis axis) throws GLib.Error { + if (!still_around ()) { + throw new GLib.Error ( + GLib.Quark.from_string ("Gamepad"), + 1, + @"The gamepad specified, $(this.padID):$(this.padName), is no longer available." + ); + } + return (Raylib.get_gamepad_axis_movement (this.padID, (Raylib.GamepadAxis) axis)); + } + + /** + * Set internal mappings (SDL_GameControllerDB) + */ + public int set_mappings (string mappings) throws GLib.Error { + if (!still_around ()) { + throw new GLib.Error ( + GLib.Quark.from_string ("Gamepad"), + 1, + @"The gamepad specified, $(this.padID):$(this.padName), is no longer available." + ); + } + return (Raylib.set_gamepad_mappings (mappings)); + } + + /* Properties */ + /** + * Get internal name id. + */ + public string name { + owned get { + /* Update pad name */ + var name = Raylib.get_gamepad_name (this.padID); + this.padName = name; + return (name); + } + } + /** + * Get the last button pressed. + */ + public Raylib.GamepadButton button_pressed { + get { + return (Raylib.get_gamepad_button_pressed ()); + } + } + /** + * Get axis count for gamepad. + */ + public int axis_count { + get { + return (Raylib.get_gamepad_axis_count (this.padID)); + } + } + } + } +} diff --git a/src/lib/Input/Keyboard.vala b/src/lib/Input/Keyboard.vala new file mode 100644 index 0000000..c7be5bc --- /dev/null +++ b/src/lib/Input/Keyboard.vala @@ -0,0 +1,175 @@ +using RaylibOOP; +using RaylibOOP.Shapes; + +namespace RaylibOOP { + namespace Input { + public class Keyboard : GLib.Object { + public enum Key { + NULL = Raylib.KeyboardKey.NULL, // Key: NULL, used for no key pressed + // Alphanumeric keys + APOSTROPHE = Raylib.KeyboardKey.APOSTROPHE, // Key: ' + COMMA = Raylib.KeyboardKey.COMMA, // Key: , + MINUS = Raylib.KeyboardKey.MINUS, // Key: - + PERIOD = Raylib.KeyboardKey.PERIOD, // Key: . + SLASH = Raylib.KeyboardKey.SLASH, // Key: / + ZERO = Raylib.KeyboardKey.ZERO, // Key: 0 + ONE = Raylib.KeyboardKey.ONE, // Key: 1 + TWO = Raylib.KeyboardKey.TWO, // Key: 2 + THREE = Raylib.KeyboardKey.THREE, // Key: 3 + FOUR = Raylib.KeyboardKey.FOUR, // Key: 4 + FIVE = Raylib.KeyboardKey.FIVE, // Key: 5 + SIX = Raylib.KeyboardKey.SIX, // Key: 6 + SEVEN = Raylib.KeyboardKey.SEVEN, // Key: 7 + EIGHT = Raylib.KeyboardKey.EIGHT, // Key: 8 + NINE = Raylib.KeyboardKey.NINE, // Key: 9 + SEMICOLON = Raylib.KeyboardKey.SEMICOLON, // Key: ; + EQUAL = Raylib.KeyboardKey.EQUAL, // Key: = + A = Raylib.KeyboardKey.A, // Key: A | a + B = Raylib.KeyboardKey.B, // Key: B | b + C = Raylib.KeyboardKey.C, // Key: C | c + D = Raylib.KeyboardKey.D, // Key: D | d + E = Raylib.KeyboardKey.E, // Key: E | e + F = Raylib.KeyboardKey.F, // Key: F | f + G = Raylib.KeyboardKey.G, // Key: G | g + H = Raylib.KeyboardKey.H, // Key: H | h + I = Raylib.KeyboardKey.I, // Key: I | i + J = Raylib.KeyboardKey.J, // Key: J | j + K = Raylib.KeyboardKey.K, // Key: K | k + L = Raylib.KeyboardKey.L, // Key: L | l + M = Raylib.KeyboardKey.M, // Key: M | m + N = Raylib.KeyboardKey.N, // Key: N | n + O = Raylib.KeyboardKey.O, // Key: O | o + P = Raylib.KeyboardKey.P, // Key: P | p + Q = Raylib.KeyboardKey.Q, // Key: Q | q + R = Raylib.KeyboardKey.R, // Key: R | r + S = Raylib.KeyboardKey.S, // Key: S | s + T = Raylib.KeyboardKey.T, // Key: T | t + U = Raylib.KeyboardKey.U, // Key: U | u + V = Raylib.KeyboardKey.V, // Key: V | v + W = Raylib.KeyboardKey.W, // Key: W | w + X = Raylib.KeyboardKey.X, // Key: X | x + Y = Raylib.KeyboardKey.Y, // Key: Y | y + Z = Raylib.KeyboardKey.Z, // Key: Z | z + LEFT_BRACKET = Raylib.KeyboardKey.LEFT_BRACKET, // Key: [ + BACKSLASH = Raylib.KeyboardKey.BACKSLASH, // Key: '\' + RIGHT_BRACKET = Raylib.KeyboardKey.RIGHT_BRACKET, // Key: ] + GRAVE = Raylib.KeyboardKey.GRAVE, // Key: ` + // Function keys + SPACE = Raylib.KeyboardKey.SPACE, // Key: Space + ESCAPE = Raylib.KeyboardKey.ESCAPE, // Key: Esc + ENTER = Raylib.KeyboardKey.ENTER, // Key: Enter + TAB = Raylib.KeyboardKey.TAB, // Key: Tab + BACKSPACE = Raylib.KeyboardKey.BACKSPACE, // Key: Backspace + INSERT = Raylib.KeyboardKey.INSERT, // Key: Ins + DELETE = Raylib.KeyboardKey.DELETE, // Key: Del + RIGHT = Raylib.KeyboardKey.RIGHT, // Key: Cursor right + LEFT = Raylib.KeyboardKey.LEFT, // Key: Cursor left + DOWN = Raylib.KeyboardKey.DOWN, // Key: Cursor down + UP = Raylib.KeyboardKey.UP, // Key: Cursor up + PAGE_UP = Raylib.KeyboardKey.PAGE_UP, // Key: Page up + PAGE_DOWN = Raylib.KeyboardKey.PAGE_DOWN, // Key: Page down + HOME = Raylib.KeyboardKey.HOME, // Key: Home + END = Raylib.KeyboardKey.END, // Key: End + CAPS_LOCK = Raylib.KeyboardKey.CAPS_LOCK, // Key: Caps lock + SCROLL_LOCK = Raylib.KeyboardKey.SCROLL_LOCK, // Key: Scroll down + NUM_LOCK = Raylib.KeyboardKey.NUM_LOCK, // Key: Num lock + PRINT_SCREEN = Raylib.KeyboardKey.PRINT_SCREEN, // Key: Print screen + PAUSE = Raylib.KeyboardKey.PAUSE, // Key: Pause + F1 = Raylib.KeyboardKey.F1, // Key: F1 + F2 = Raylib.KeyboardKey.F2, // Key: F2 + F3 = Raylib.KeyboardKey.F3, // Key: F3 + F4 = Raylib.KeyboardKey.F4, // Key: F4 + F5 = Raylib.KeyboardKey.F5, // Key: F5 + F6 = Raylib.KeyboardKey.F6, // Key: F6 + F7 = Raylib.KeyboardKey.F7, // Key: F7 + F8 = Raylib.KeyboardKey.F8, // Key: F8 + F9 = Raylib.KeyboardKey.F9, // Key: F9 + F10 = Raylib.KeyboardKey.F10, // Key: F10 + F11 = Raylib.KeyboardKey.F11, // Key: F11 + F12 = Raylib.KeyboardKey.F12, // Key: F12 + LEFT_SHIFT = Raylib.KeyboardKey.LEFT_SHIFT, // Key: Shift left + LEFT_CONTROL = Raylib.KeyboardKey.LEFT_CONTROL, // Key: Control left + LEFT_ALT = Raylib.KeyboardKey.LEFT_ALT, // Key: Alt left + LEFT_SUPER = Raylib.KeyboardKey.LEFT_SUPER, // Key: Super left + RIGHT_SHIFT = Raylib.KeyboardKey.RIGHT_SHIFT, // Key: Shift right + RIGHT_CONTROL = Raylib.KeyboardKey.RIGHT_CONTROL, // Key: Control right + RIGHT_ALT = Raylib.KeyboardKey.RIGHT_ALT, // Key: Alt right + RIGHT_SUPER = Raylib.KeyboardKey.RIGHT_SUPER, // Key: Super right + KB_MENU = Raylib.KeyboardKey.KB_MENU, // Key: KB menu + KP_0 = Raylib.KeyboardKey.KP_0, // Key: Keypad 0 + KP_1 = Raylib.KeyboardKey.KP_1, // Key: Keypad 1 + KP_2 = Raylib.KeyboardKey.KP_2, // Key: Keypad 2 + KP_3 = Raylib.KeyboardKey.KP_3, // Key: Keypad 3 + KP_4 = Raylib.KeyboardKey.KP_4, // Key: Keypad 4 + KP_5 = Raylib.KeyboardKey.KP_5, // Key: Keypad 5 + KP_6 = Raylib.KeyboardKey.KP_6, // Key: Keypad 6 + KP_7 = Raylib.KeyboardKey.KP_7, // Key: Keypad 7 + KP_8 = Raylib.KeyboardKey.KP_8, // Key: Keypad 8 + KP_9 = Raylib.KeyboardKey.KP_9, // Key: Keypad 9 + KP_DECIMAL = Raylib.KeyboardKey.KP_DECIMAL, // Key: Keypad . + KP_DIVIDE = Raylib.KeyboardKey.KP_DIVIDE, // Key: Keypad / + KP_MULTIPLY = Raylib.KeyboardKey.KP_MULTIPLY, // Key: Keypad * + KP_SUBTRACT = Raylib.KeyboardKey.KP_SUBTRACT, // Key: Keypad - + KP_ADD = Raylib.KeyboardKey.KP_ADD, // Key: Keypad + + KP_ENTER = Raylib.KeyboardKey.KP_ENTER, // Key: Keypad Enter + KP_EQUAL = Raylib.KeyboardKey.KP_EQUAL, // Key: Keypad = + BACK = Raylib.KeyboardKey.BACK, // Key: Android back button + MENU = Raylib.KeyboardKey.MENU, // Key: Android menu button + VOLUME_UP = Raylib.KeyboardKey.VOLUME_UP, // Key: Android volume up button + VOLUME_DOWN = Raylib.KeyboardKey.VOLUME_DOWN // Key: Android volume down button + + } + private Keyboard() { + return; + } + /* Methods */ + /** + * Check if a key has been pressed once. + */ + public static bool is_pressed(int key) { + return(Raylib.is_key_pressed(key)); + } + /** + * Check if a key has been pressed again (Only PLATFORM_DESKTOP) + */ + public static bool is_pressed_repeat(int key) { + return(Raylib.is_key_pressed_repeat(key)); + } + /** + * Check if a key is being pressed. + */ + public static bool is_down(int key) { + return(Raylib.is_key_down(key)); + } + /** + * Check if a key has been released once. + */ + public static bool is_released(int key) { + return(Raylib.is_key_released(key)); + } + /** + * Check if a key is NOT being pressed. + */ + public static bool is_up(int key) { + return(Raylib.is_key_up(key)); + } + /* Properties */ + /** + * Get key pressed (keycode), call it multiple times for keys queued, returns 0 when the queue is empty. + */ + public static int key_pressed { + get { + return(Raylib.get_key_pressed()); + } + } + /** + * Get char pressed (unicode), call it multiple times for chars queued, returns 0 when the queue is empty. + */ + public static int char_pressed { + get { + return(Raylib.get_char_pressed()); + } + } + } + } +} diff --git a/src/lib/Input/Mouse.vala b/src/lib/Input/Mouse.vala new file mode 100644 index 0000000..15f4f26 --- /dev/null +++ b/src/lib/Input/Mouse.vala @@ -0,0 +1,148 @@ +using RaylibOOP.Shapes; + +namespace RaylibOOP { + namespace Input { + public class Mouse : GLib.Object { + /* Variables */ + internal static Raylib.Vector2 scaleVector = {1, 1}; + internal static Raylib.Vector2 offsetVector = {0, 0}; + public enum Button { /* I wish there was a better way to do this */ + LEFT = Raylib.MouseButton.LEFT, + RIGHT = Raylib.MouseButton.RIGHT, + MIDDLE = Raylib.MouseButton.MIDDLE, + SIDE = Raylib.MouseButton.SIDE, + EXTRA = Raylib.MouseButton.EXTRA, + FORWARD = Raylib.MouseButton.FORWARD, + BACK = Raylib.MouseButton.BACK, + } + public enum Cursor { + DEFAULT = Raylib.MouseCursor.DEFAULT, + ARROW = Raylib.MouseCursor.ARROW, + IBEAM = Raylib.MouseCursor.IBEAM, + CROSSHAIR = Raylib.MouseCursor.CROSSHAIR, + POINTING_HAND = Raylib.MouseCursor.POINTING_HAND, + RESIZE_EW = Raylib.MouseCursor.RESIZE_EW, + RESIZE_NS = Raylib.MouseCursor.RESIZE_NS, + RESIZE_NWSE = Raylib.MouseCursor.RESIZE_NWSE, + RESIZE_NESW = Raylib.MouseCursor.RESIZE_NESW, + RESIZE_ALL = Raylib.MouseCursor.RESIZE_ALL, + NOT_ALLOWED = Raylib.MouseCursor.NOT_ALLOWED + } + private Mouse() { + return; + } + /* Methods */ + /** + * Check if a mouse button has been pressed once + */ + public static bool is_pressed(int button) { + return(Raylib.is_mouse_button_pressed(button)); + } + /** + * Check if a mouse button is being pressed + */ + public static bool is_down(int button) { + return(Raylib.is_mouse_button_down(button)); + } + /** + * Check if a mouse button has been released once + */ + public static bool is_released(int button) { + return(Raylib.is_mouse_button_released(button)); + } + /** + * Check if a mouse button is NOT being pressed + */ + public static bool is_up(int button) { + return(Raylib.is_mouse_button_up(button)); + } + /** + * Set mouse cursor + */ + public static void set_cursor(int cursor) { + Raylib.set_mouse_cursor(cursor); + return; + } + /* Properties */ + /** + * Mouse position XY + */ + public static Vector2 position { + owned get { + Raylib.Vector2 a = Raylib.get_mouse_position(); + return(new Vector2(a.x, a.y)); + } + set { + Vector2 a = value; + Raylib.set_mouse_position((int)Math.ceilf(a.x), (int)Math.ceilf(a.y)); + } + } + /** + * Mouse delta between frames + */ + public static Vector2 delta { + owned get { + Raylib.Vector2 a = Raylib.get_mouse_delta(); + return(new Vector2(a.x, a.y)); + } + } + /** + * Mouse scaling + */ + public static Vector2 scale { + owned get { + return(new Vector2(scaleVector.x, scaleVector.y)); + } + set { + Vector2 a = value; + Raylib.set_mouse_scale(a.x, a.y); + } + } + /** + * Mouse offset + */ + public static Vector2 offset { + owned get { + return(new Vector2(offsetVector.x, offsetVector.y)); + } + set { + Vector2 a = value; + offsetVector.x = a.x; + offsetVector.y = a.y; + Raylib.set_mouse_offset((int)Math.ceilf(a.x), (int)Math.ceilf(a.y)); + } + } + /** + * Mouse position X + */ + public static int x { + get { + return(Raylib.get_mouse_x()); + } + set { + Raylib.set_mouse_position(value, Raylib.get_mouse_y()); + } + } + /** + * Mouse position Y + */ + public static int y { + get { + return(Raylib.get_mouse_y()); + } + set { + Raylib.set_mouse_position(Raylib.get_mouse_x(), value); + } + } + /** + * Mouse wheel movement for both X and Y + */ + public static Vector2 wheel_move { + owned get { + var a = Raylib.get_mouse_wheel_move_vector(); + return(new Vector2(a.x, a.y)); + } + } + } + } +} diff --git a/src/lib/Input/Touch.vala b/src/lib/Input/Touch.vala new file mode 100644 index 0000000..716fc3f --- /dev/null +++ b/src/lib/Input/Touch.vala @@ -0,0 +1,128 @@ +using RaylibOOP.Shapes; + +namespace RaylibOOP { + namespace Input { + public class Touch : GLib.Object { + /* Variables */ + public enum Gestures { + DOUBLE_TAP = Raylib.Gesture.DOUBLETAP, + DRAG = Raylib.Gesture.DRAG, + HOLD = Raylib.Gesture.HOLD, + NONE = Raylib.Gesture.NONE, + PINCH_IN = Raylib.Gesture.PINCH_IN, + PINCH_OUT = Raylib.Gesture.PINCH_OUT, + SWIPE_DOWN = Raylib.Gesture.SWIPE_DOWN, + SWIPE_LEFT = Raylib.Gesture.SWIPE_LEFT, + SWIPE_RIGHT = Raylib.Gesture.SWIPE_RIGHT, + SWIPE_UP = Raylib.Gesture.SWIPE_UP, + TAP = Raylib.Gesture.TAP, + } + private Touch() { + return; + } + /* Methods */ + /** + * Get touch position XY for a touch point index (relative to screen size) + */ + public static Vector2 get_position(int index) { + var a = Raylib.get_touch_position(index); + return(new Vector2(a.x, a.y)); + } + /** + * Get touch point identifier for given index. + */ + public static int get_id(int index) { + return(Raylib.get_touch_point_id(index)); + } + /* Gestures */ + /** + * Enable a set of gestures using flags + */ + public static void enable_gestures(int gestures) { + Raylib.set_gestures_enabled(gestures); + } + /** + * Check if a gesture have been detected + */ + public static bool is_gesture_detected(int gesture) { + return(Raylib.is_gesture_detected(gesture)); + } + /* Properties */ + /** + * Touch position X for touch point 0 (relative to screen size) + */ + public static int x { + get { + return(Raylib.get_touch_x()); + } + } + /** + * Touch position Y for touch point 0 (relative to screen size) + */ + public static int y { + get { + return(Raylib.get_touch_y()); + } + } + /** + * Get number of touch points. + */ + public static int point_count { + get { + return(Raylib.get_touch_point_count()); + } + } + /* Gestures */ + /** + * Get latest detected gesture + */ + public static int detected_gesture { + get { + return(Raylib.get_gesture_detected()); + } + } + /** + * Gesture hold time in milliseconds + */ + public static float hold_duration { + get { + return(Raylib.get_gesture_hold_duration()); + } + } + /** + * Gesture drag vector + */ + public static Vector2 drag_vector { + owned get { + var a = Raylib.get_gesture_drag_vector(); + return(new Vector2(a.x, a.y)); + } + } + /** + * Gesture drag angle + */ + public static float drag_angle { + get { + return(Raylib.get_gesture_drag_angle()); + } + } + /** + * Gesture pinch delta + */ + public static Vector2 pinch_vector { + owned get { + var a = Raylib.get_gesture_pinch_vector(); + return(new Vector2(a.x, a.y)); + } + } + /** + * Gesture pinch angle + */ + public static float pinch_angle { + get { + return(Raylib.get_gesture_pinch_angle()); + } + } + } + } +} diff --git a/src/lib/Log.vala b/src/lib/Log.vala new file mode 100644 index 0000000..aae66b0 --- /dev/null +++ b/src/lib/Log.vala @@ -0,0 +1,45 @@ +namespace RaylibOOP { + public class Log : GLib.Object { + public enum Level { + ALL = Raylib.TraceLogLevel.ALL, + TRACE = Raylib.TraceLogLevel.TRACE, + DEBUG = Raylib.TraceLogLevel.DEBUG, + INFO = Raylib.TraceLogLevel.INFO, + WARNING = Raylib.TraceLogLevel.WARNING, + ERROR = Raylib.TraceLogLevel.ERROR, + FATAL = Raylib.TraceLogLevel.FATAL, + NONE = Raylib.TraceLogLevel.NONE, + } + private Log() { + return; + } + internal static void trace_log(int log_level, string text, va_list args) { + /* I have no idea why I have to create this string, but it'll segfault + * otherwise =( */ + string res = "[Raylib] "+text.vprintf(args); + switch(log_level) { + case Level.ALL: + message(res); + break; + case Level.TRACE: + info(res); + break; + case Level.DEBUG: + debug(res); + break; + case Level.INFO: + info(res); + break; + case Level.WARNING: + warning(res); + break; + case Level.ERROR: + error(res); + case Level.FATAL: + error(@"FATAL: $(res)"); + default: + break; + } + } + } +} diff --git a/src/lib/Shapes/Line.vala b/src/lib/Shapes/Line.vala new file mode 100644 index 0000000..1932515 --- /dev/null +++ b/src/lib/Shapes/Line.vala @@ -0,0 +1,56 @@ +using GLib; +using RaylibOOP; +using RaylibOOP.Shapes; + +namespace RaylibOOP { + namespace Shapes { + public class Line : Object { + private Line() { + return; + } + /* Methods */ + /** + * Draw basic line. + */ + public static void draw(Vector2 startPosition, Vector2 endPosition, Color color) { + Raylib.draw_line((int)startPosition.x, (int)startPosition.y, (int)endPosition.x, (int)endPosition.y, color.iColor); + } + /** + * Draw line using gl lines. + */ + public static void draw_gl(Vector2 startPosition, Vector2 endPosition, float? thickness, Color color) { + if(thickness == null) { + Raylib.draw_line_vector(startPosition.iVector, endPosition.iVector, color.iColor); + } else { + Raylib.draw_line_ext(startPosition.iVector, endPosition.iVector, thickness, color.iColor); + } + } + /** + * Draw lines sequence. + */ + public static void draw_strip(Vector2[] points, Color color) { + /* Create an array containing the Vector2 object's internal raylib struct (iVector) */ + /* For the future: Using a normal array rather than the GLib.Array object due to + * compilation failures on (stable). If the vala compilers updates there, change this + * to a GLib.Array object to reduce code size. */ + Raylib.Vector2[] v = new Raylib.Vector2[1]; + int vsize = 0; + foreach (var i in points) { + vsize++; + int element = vsize-1; + v.resize(vsize); + v[element].x = i.iVector.x; + v[element].y = i.iVector.y; + } + Raylib.draw_line_strip(v, color.iColor); + } + /** + * Draw line segment cubic-bezier in-out interpolation + */ + public static void draw_bezier(Vector2 startPosition, Vector2 endPosition, float thickness, Color color) { + Raylib.draw_line_bezier(startPosition.iVector, endPosition.iVector, thickness, color.iColor); + } + + } + } +} \ No newline at end of file diff --git a/src/lib/Shapes/Rectangle.vala b/src/lib/Shapes/Rectangle.vala new file mode 100644 index 0000000..fcf4472 --- /dev/null +++ b/src/lib/Shapes/Rectangle.vala @@ -0,0 +1,107 @@ +using GLib; +using Raylib; + +namespace RaylibOOP { + namespace Shapes { + public class Rectangle : Object { + internal Raylib.Rectangle iRectangle; + /* Constructors */ + public Rectangle(float x, float y, float width, float height) { + iRectangle.x = x; + iRectangle.y = y; + iRectangle.width = width; + iRectangle.height = height; + } + /* Methods */ + /** + * Draws the rectangle. + */ + public void draw(Color color, Shapes.Vector2? origin, float? rotation) { + Shapes.Vector2 o; + if(origin == null) { + o = new Shapes.Vector2(0, 0); + } else { + o = origin; + } + if(rotation == null) { + rotation = 0; + } + Raylib.draw_rectangle_pro(iRectangle, o.iVector, rotation, color.iColor); + return; + } + /** + * Draws the rectangle with a gradient. + */ + public void draw_gradient(Color colorA, Color colorB, Color colorC, Color colorD) { + Raylib.draw_rectangle_gradient_ext(iRectangle, colorA.iColor, colorB.iColor, colorC.iColor, colorD.iColor); + return; + } + /** + * Draws outline of the rectangle. + */ + public void draw_outline(float thickness, Color color) { + Raylib.draw_rectangle_lines_ext(iRectangle, thickness, color.iColor); + return; + } + /** + * Draw a rectangle with rounded corners. + */ + public void draw_rounded(float roundness, int segments, float thickness, Color color) { + Raylib.draw_rectangle_rounded(iRectangle, roundness, segments, color.iColor); + return; + } + /** + * Draw a rectangle outline with rounded corners. + */ + public void draw_rounded_outline(float roundness, int segments, float thickness, Color color) { + Raylib.draw_rectangle_rounded_lines(iRectangle, roundness, segments, thickness, color.iColor); + return; + } + /* Properties */ + /** + * X position of rectangle. + */ + public float x { + get { + return(iRectangle.x); + } + set { + iRectangle.x = value; + } + } + /** + * Y position of rectangle. + */ + public float y { + get { + return(iRectangle.y); + } + set { + iRectangle.y = value; + } + } + /** + * Width of rectangle. + */ + public float width { + get { + return(iRectangle.width); + } + set { + iRectangle.width = value; + } + } + /** + * Height of rectangle. + */ + public float height { + get { + return(iRectangle.height); + } + set { + iRectangle.height = value; + } + } + } + } +} \ No newline at end of file diff --git a/src/lib/Shapes/Vector2.vala b/src/lib/Shapes/Vector2.vala new file mode 100644 index 0000000..7770dd9 --- /dev/null +++ b/src/lib/Shapes/Vector2.vala @@ -0,0 +1,47 @@ +namespace RaylibOOP { + namespace Shapes { + public class Vector2 : GLib.Object { + /* Variables */ + public Raylib.Vector2 iVector; + /* Constructor */ + public Vector2(float x, float y) { + this.iVector.x = x; + this.iVector.y = y; + } + /* Methods */ + public void draw_line(Shapes.Vector2 other, Raylib.Color color, float? thickness) { + /* Prep */ + if(thickness == null) { + thickness = 1; + } + /* Calls */ + Raylib.draw_line_ext(this.iVector, other.iVector, thickness, color); + return; + } + public void draw_pixel(Raylib.Color color) { + Raylib.draw_pixel_vector(this.iVector, color); + return; + } + public void draw_circle() { + + } + /* Properties */ + public float x { + get { + return(this.iVector.x); + } + set { + this.iVector.x = value; + } + } + public float y { + get { + return(this.iVector.y); + } + set { + this.iVector.y = value; + } + } + } + } +} diff --git a/src/lib/Text.vala b/src/lib/Text.vala new file mode 100644 index 0000000..9840807 --- /dev/null +++ b/src/lib/Text.vala @@ -0,0 +1,64 @@ +namespace RaylibOOP { + public class Font : GLib.Object { + internal Raylib.Font iFont; + /* Default font, see Window object for initialization */ + public static Font DEFAULT; + /* Constructors */ + /** + * Load font from file. + */ + public Font(string? fontFile) { + if(fontFile == null) { + iFont = Raylib.get_font_default(); + } else { + iFont = Raylib.load_font(fontFile); + } + } + /** + * Loads font from memory. + */ + public Font.from_memory(uint8[] font, string type, int size, int[] characters) { + iFont = Raylib.load_font_from_memory(type, font, size, characters); + return; + } + /* Initializes default font */ + internal Font.default() { + iFont = Raylib.get_font_default(); + } + /* Destructor */ + ~Font() { + Raylib.unload_font(iFont); + } + /* Methods */ + /** + * Exports font data as C Code. + * If you want vala code, please see bin2vala. + */ + public void export_as_code(string file) throws GLib.FileError { + if(Raylib.export_font_as_code(this.iFont, file) == true) { + return; + } + throw new GLib.FileError.FAILED("Failed to export font as code."); + } + /** + * Draw text on screen. + */ + public void draw_text(string text, Shapes.Vector2 xy, float size, float? spacing, Color color) { + float s; + float defaultFontSize = 10; + if(spacing == null) { + s = size/defaultFontSize; + } else { + s = spacing; + } + Raylib.draw_text_ext(this.iFont, text, xy.iVector, size, s, color.iColor); + return; + } + /* Properties */ + public bool ready { + get { + return(Raylib.is_font_ready(this.iFont)); + } + } + } +} diff --git a/src/lib/Util.vala b/src/lib/Util.vala new file mode 100644 index 0000000..0039b18 --- /dev/null +++ b/src/lib/Util.vala @@ -0,0 +1,31 @@ +namespace RaylibOOP { + namespace Util { + public uint8 hex_to_uint8(char a) { + uint8 base10_a; + switch(a.tolower()) { + case 'a': + base10_a = 10; + break; + case 'b': + base10_a = 11; + break; + case 'c': + base10_a = 12; + break; + case 'd': + base10_a = 13; + break; + case 'e': + base10_a = 14; + break; + case 'f': + base10_a = 15; + break; + default: + base10_a = (uint8)a.digit_value(); + break; + } + return(base10_a); + } + } +} diff --git a/src/lib/Window.vala b/src/lib/Window.vala new file mode 100644 index 0000000..0266160 --- /dev/null +++ b/src/lib/Window.vala @@ -0,0 +1,569 @@ +using RaylibOOP.Shapes; + +namespace RaylibOOP { + public errordomain WindowError { + ONLY_ONE, + NO_DROPPED_FILES + } + /* Prevents 2 Window objects from existing */ + internal uint8 numOfWindows = 0; + + public class Window : GLib.Object { + /* Objects */ + public class Cursor { + /* Variables */ + internal bool cursorLocked = false; + /* Methods */ + /* Properties */ + /** + * If cursor is not visible + */ + public bool hidden { + get { + return(Raylib.is_cursor_hidden()); + } + set { + if(value == true) { + Raylib.hide_cursor(); + } else { + Raylib.show_cursor(); + } + } + } + /** + * If cursor is locked. + */ + public bool locked { + get { + return(cursorLocked); + } + set { + if(value == true) { + cursorLocked = true; + Raylib.disable_cursor(); + } else { + cursorLocked = false; + Raylib.enable_cursor(); + } + } + } + /** + * If cursor is on the screen + */ + public bool on_screen { + get { + return(Raylib.is_cursor_on_screen()); + } + } + } + public class Monitor { + private int num; + public Monitor(int monitorNum) { + this.num = monitorNum; + } + /* Properties */ + /** + * Get monitor width (current video mode used by monitor) + */ + public int width { + get { + return(Raylib.get_monitor_width(num)); + } + } + /** + * Get monitor height (current video mode used by monitor) + */ + public int height { + get { + return(Raylib.get_monitor_height(num)); + } + } + /** + * Get monitor refresh rate + */ + public int refresh_rate { + get { + return(Raylib.get_monitor_refresh_rate(num)); + } + } + /** + * Get the human-readable, UTF-8 encoded name of the monitor + */ + public string name { + owned get { + return(Raylib.get_monitor_name(num)); + } + } + /** + * Get monitor physical width in millimetres + */ + public int physical_width { + get { + return(Raylib.get_monitor_physical_width(num)); + } + } + /** + * Get monitor physical height in millimetres + */ + public int physical_height { + get { + return(Raylib.get_monitor_physical_height(num)); + } + } + } + /* Variables */ + internal string windowTitle = "Raylib"; + internal int targetFPS = 60; + internal Input.Keyboard.Key exitKey = Input.Keyboard.Key.ESCAPE; + internal int minimumHeight = 0; + internal int minimumWidth = 0; + internal int maximumHeight = 0; + internal int maximumWidth = 0; + internal bool eventRecording = false; + internal bool eventListSet = false; + internal bool eventWaiting = false; + public Cursor cursor; + public Monitor[] monitors; + /* Constructor */ + public Window(int width, int height, string title) throws WindowError { + /* Check that only 1 window is active. */ + if(numOfWindows > 0) { + throw new WindowError.ONLY_ONE("You can only have one Window at a time."); + } + + warning("The OOP interface is not done. Here be dragons!"); + + /* Make raylib use GLib's logging system */ + Raylib.set_trace_log_callback(Log.trace_log); + /* Initialize the Window */ + this.windowTitle = title; + Raylib.init_window(width, height, this.windowTitle); + if(Raylib.is_window_ready() == false) + error("Could not initialize window."); + this.target_fps = targetFPS; + /* Initialize Default Font */ + Font.DEFAULT = new Font.default(); + /* Create Cursor Object */ + cursor = new Cursor(); + /* Create Monitor Array */ + monitors.resize(monitors.length+1); + monitors[0] = new Monitor(0); + for(int i = 1; i < Raylib.get_monitor_count(); i++) { + monitors.resize(monitors.length+1); + monitors[i] = new Monitor(i); + } + numOfWindows++; + } + /* Destroyer */ + ~Window() { + debug("Destroying Window..."); + Raylib.close_window(); + numOfWindows--; + } + /* Methods */ + /** + * Set automation event list to record to. + */ + public void set_automation_event_list(Automation.EventList eventList) { + Raylib.set_automation_event_list(&eventList.eventList); + eventListSet = true; + } + /** + * Get current connected monitor + */ + public Monitor* get_current_monitor() { + return(this.monitors[Raylib.get_current_monitor()]); + } + /** + * Set automation event internal base frame to start recording + */ + public void set_automation_event_base_frame(int frame) { + Raylib.set_automation_event_base_frame(frame); + } + /** + * Play a recorded automation event + */ + public void play_automation_event(Raylib.AutomationEvent event) { + Raylib.play_automation_event(event); + } + /** + * Scissor mode (define screen area for following drawing) + */ + public void scissor(int x, int y, int width, int height, Func func) { + Raylib.begin_scissor_mode(x, y, width, height); + func(null); + Raylib.end_scissor_mode(); + } + /** + * Begin scissor mode (define screen area for following drawing) + */ + public void begin_scissor(int x, int y, int width, int height) { + Raylib.begin_scissor_mode(x, y, width, height); + } + /** + * End scissor mode. + */ + public void end_scissor() { + Raylib.end_scissor_mode(); + } + /** + * Load dropped filepaths + */ + public void get_dropped_files(out GLib.Array files) throws WindowError { + if(file_dropped == false) { + throw new WindowError.NO_DROPPED_FILES("No files were dropped."); + } + files = new GLib.Array(); + Raylib.FilePathList a = Raylib.load_dropped_files(); + for(int i = 0; i < a.paths.length; i++) { + files.append_val(a.paths[i]); + debug(a.paths[i]); + } + Raylib.unload_dropped_files(a); + } + /** + * Take Screenshot + */ + public void take_screenshot(string filename) { + Raylib.take_screenshot(filename); + } + /** + * Set window state: not minimized/maximized (only PLATFORM_DESKTOP) + */ + public void restore() { + Raylib.restore_window(); + } + /** + * Draws current framerate at coordinates. + */ + public void draw_fps(int x, int y) { + Raylib.draw_fps(x, y); + return; + } + /** + * Draw Frame + */ + public void draw(Func function) { + this.begin_drawing(); + function(null); + this.end_drawing(); + } + /** + * Setup canvas (framebuffer) to start drawing + */ + public void begin_drawing() { + Raylib.begin_drawing(); + } + /** + * End canvas drawing and swap buffers (double buffering) + */ + public void end_drawing() { + Raylib.end_drawing(); + } + /** + * Set background color (framebuffer clear color) + */ + public void clear_background(Color color) { + Raylib.Color a = { + color.r, color.g, color.b, color.a, + }; + Raylib.clear_background(a); + } + /* Properties */ + /** + * If window is ready. + */ + public bool ready { + get { return(Raylib.is_window_ready()); } + } + /** + * If window should close. + */ + public bool should_close { + get { + return(Raylib.window_should_close()); + } + } + /** + * Is window fullscreen. + */ + public bool fullscreen { + get { return(Raylib.is_window_fullscreen()); } + set { + if(value == true) + Raylib.set_window_state(Raylib.ConfigFlags.FULLSCREEN_MODE); + else + Raylib.clear_window_state(Raylib.ConfigFlags.FULLSCREEN_MODE); + } + } + /** + * Borderless windowed (only PLATFORM_DESKTOP) + */ + public bool borderless { + get { + return(Raylib.is_window_state(Raylib.ConfigFlags.BORDERLESS_WINDOWED_MODE)); + } + set { + Raylib.set_window_state(Raylib.ConfigFlags.BORDERLESS_WINDOWED_MODE); + } + } + /** + * Is window hidden. + */ + public bool hidden { + get { return(Raylib.is_window_hidden()); } + set { + if(value == true) + Raylib.set_window_state(Raylib.ConfigFlags.WINDOW_HIDDEN); + else + Raylib.clear_window_state(Raylib.ConfigFlags.WINDOW_HIDDEN); + } + } + /** + * Is window minimized. + */ + public bool minimized { + get { return(Raylib.is_window_minimized()); } + set { + if(value == true) + Raylib.set_window_state(Raylib.ConfigFlags.WINDOW_MINIMIZED); + else + Raylib.clear_window_state(Raylib.ConfigFlags.WINDOW_MINIMIZED); + } + } + /** + * Is window maximized. + */ + public bool maximized { + get { return(Raylib.is_window_maximized()); } + set { + if(value == true) + Raylib.set_window_state(Raylib.ConfigFlags.WINDOW_MAXIMIZED); + else + Raylib.clear_window_state(Raylib.ConfigFlags.WINDOW_MAXIMIZED); + } + } + /** + * Is window focused. + */ + public bool focused { + get { return(Raylib.is_window_focused()); } + } + /** + * If window has been resized. + */ + public bool resized { + get { return(Raylib.is_window_resized()); } + } + /** + * Master volume of the window + */ + public float master_volume { + get { + return(Raylib.get_master_volume()); + } + set { + float volume = value; + if(volume > 1.0f) { + volume = 1.0f; + } else if(volume < 0.0f) { + volume = 0.0f; + } + Raylib.set_master_volume(volume); + } + } + /** + * Title of the window + */ + public string title { + get { + return(this.windowTitle); + } + set { + this.windowTitle = value; + Raylib.set_window_title(this.windowTitle); + } + } + /** + * Current Frames per Second of the Window. + */ + public int fps { + get { + return(Raylib.get_fps()); + } + } + /** + * Target FPS of the Window. + */ + public int target_fps { + get { + return(this.targetFPS); + } + set { + Raylib.set_target_fps(value); + this.targetFPS = value; + } + } + /** + * The exit key of the window. + */ + public Input.Keyboard.Key exit_key { + get { + return(this.exitKey); + } + set { + this.exitKey = value; + Raylib.set_exit_key(value); + } + } + /** + * Screen width + */ + public int width { + get { + return(Raylib.get_screen_width()); + } + set { + Raylib.set_window_size(value, Raylib.get_screen_height()); + } + } + /** + * Screen Height + */ + public int height { + get { + return(Raylib.get_screen_height()); + } + set { + Raylib.set_window_size(Raylib.get_screen_width(), value); + } + } + /** + * Minimum Height of Window. A value of 0 means unset. + */ + public int minimum_height { + get { + return(this.minimumHeight); + } + set { + minimumHeight = value; + Raylib.set_window_minimum_size(minimumWidth, value); + } + } + /** + * Minimum Width of Window. Value of 0 means unset. + */ + public int minimum_width { + get { + return(this.minimumWidth); + } + set { + minimumWidth = value; + Raylib.set_window_minimum_size(value, minimumHeight); + } + } + /** + * Maximum Height of Window. A value of 0 means unset. + */ + public int maximum_height { + get { + return(this.maximumHeight); + } + set { + this.maximumHeight = value; + Raylib.set_window_maximum_size(this.maximumWidth, value); + } + } + /** + * Maximum Width of Window. A value of 0 means unset. + */ + public int maximum_width { + get { + return(this.maximumWidth); + } + set { + this.maximumWidth = value; + Raylib.set_window_maximum_size(value, this.maximumHeight); + } + } + /** + * Position of window. + */ + public Vector2 position { + owned get { + var a = Raylib.get_window_position(); + return(new Vector2(a.x, a.y)); + } + set { + Vector2 a = value; + Raylib.set_window_position((int)Math.ceilf(a.x),(int)Math.ceilf(a.y)); + a = null; + } + } + /** + * Elapsed time in seconds since window creation. + */ + public double time { + get { + return(Raylib.get_time()); + } + } + /** + * Time in seconds for last frame drawn (delta time) + */ + public float frame_time { + get { + return(Raylib.get_frame_time()); + } + } + /** + * If a file has been dropped into window + */ + public bool file_dropped { + get { + return(Raylib.is_file_dropped()); + } + } + /** + * Recording automation events (set_automation_event_list must have been run) + */ + public bool record_automation_events { + get { + if(eventListSet == false) { + return(false); + } + return(eventRecording); + } + set { + if(eventListSet == true) { + if(value == true) { + Raylib.start_automation_event_recording(); + eventRecording = true; + } else { + Raylib.stop_automation_event_recording(); + eventRecording = false; + } + } + } + } + /** + * Waiting for events on EndDrawing() + * true: no automatic event polling. + * false: automatic event polling. + */ + public bool event_waiting { + get { + return(this.eventWaiting); + } + set { + if(value == true) { + Raylib.disable_event_waiting(); + this.eventWaiting = true; + } else { + Raylib.enable_event_waiting(); + this.eventWaiting = false; + } + } + } + } +} diff --git a/src/lib/meson.build b/src/lib/meson.build new file mode 100644 index 0000000..62b02df --- /dev/null +++ b/src/lib/meson.build @@ -0,0 +1,20 @@ +raylib_oop_src = [ + 'src/lib/Shapes/Vector2.vala', + 'src/lib/Shapes/Rectangle.vala', + 'src/lib/Shapes/Line.vala', + 'src/lib/Window.vala', + 'src/lib/Color.vala', + 'src/lib/Util.vala', + 'src/lib/2DCamera.vala', + 'src/lib/Audio/Types.vala', + 'src/lib/Audio/Music.vala', + 'src/lib/Audio/Sound.vala', + 'src/lib/Input/Mouse.vala', + 'src/lib/Input/Keyboard.vala', + 'src/lib/Input/Gamepad.vala', + 'src/lib/Input/Touch.vala', + 'src/lib/Clipboard.vala', + 'src/lib/Log.vala', + 'src/lib/Automation/EventList.vala', + 'src/lib/Text.vala', +] diff --git a/src/lib/todos/core.md b/src/lib/todos/core.md new file mode 100644 index 0000000..debdbfe --- /dev/null +++ b/src/lib/todos/core.md @@ -0,0 +1,200 @@ +- [x] void InitWindow(int width, int height, const char *title); # Implemented: `new Window` +- [x] void CloseWindow(void); # Implemented: `Window = null` +- [x] bool WindowShouldClose(void); # Implemented: `Window.should_close` +- [x] bool IsWindowReady(void); # Implemented: `Window.ready` +- [x] bool IsWindowFullscreen(void); # Implemented: `Window.fullscreen` +- [x] bool IsWindowHidden(void); # Implemented: `Window.hidden` +- [x] bool IsWindowMinimized(void); # Implemented: `Window.minimized` +- [x] bool IsWindowMaximized(void); # Implemented: `Window.maximized` +- [x] bool IsWindowFocused(void); # Implemented: `Window.focused` +- [x] bool IsWindowResized(void); # Implemented: `Window.resized` +- ❌ bool IsWindowState(unsigned int flag); # Unneeded +- ❌ void SetWindowState(unsigned int flags); # Unneeded +- ❌ void ClearWindowState(unsigned int flags); # Unneeded +- [x] void ToggleFullscreen(void); # Implemented: `Window.fullscreen` +- [x] void ToggleBorderlessWindowed(void); # Implemented: `Window.borderless` +- [x] void MaximizeWindow(void); # Implemented: `Window.maximized` +- [x] void MinimizeWindow(void); # Implemented: `Window.minimized` +- [x] void RestoreWindow(void); # Implemented: `Window.restore` +- [ ] void SetWindowIcon(Image image); +- [ ] void SetWindowIcons(Image *images, int count); +- [x] void SetWindowTitle(const char *title); # Implemented: `Window.title` +- [x] void SetWindowPosition(int x, int y); # Implemented: `Window.position` +- [ ] void SetWindowMonitor(int monitor); +- [x] void SetWindowMinSize(int width, int height); # Implemented: `Window.minimum_width` and `Window.minimum_height` +- [ ] void SetWindowMaxSize(int width, int height); +- [x] void SetWindowSize(int width, int height); # Implemented: `Window.width` and `Window.height` +- [ ] void SetWindowOpacity(float opacity); +- [ ] void SetWindowFocused(void); +- [ ] void *GetWindowHandle(void); +- [x] int GetScreenWidth(void); # Implemented: `Window.width` +- [x] int GetScreenHeight(void); # Implemented: `Window.height` +- [ ] int GetRenderWidth(void); +- [ ] int GetRenderHeight(void); +- [x] int GetMonitorCount(void); # Implemented: `Window.monitors.length` +- [x] int GetCurrentMonitor(void); # Implemented: `Window.get_current_monitor` +- [ ] Vector2 GetMonitorPosition(int monitor); +- [x] int GetMonitorWidth(int monitor); # Implemented: `Window.monitors[x].width` +- [x] int GetMonitorHeight(int monitor); # Implemented: `Window.monitors[x].height` +- [x] int GetMonitorPhysicalWidth(int monitor); # Implemented: `Window.monitors[x].physical_width` +- [x] int GetMonitorPhysicalHeight(int monitor); # Implemented: `Window.monitors[x].physical_height` +- [x] int GetMonitorRefreshRate(int monitor); # Implemented: `Window.monitors[x].refresh_rate` +- [x] Vector2 GetWindowPosition(void); # Implemented: `Window.position` +- [ ] Vector2 GetWindowScaleDPI(void); +- [x] const char *GetMonitorName(int monitor); # Implemented: `Window.monitors[x].name` +- [x] void SetClipboardText(const char *text); # Implemented: `Clipboard.set` +- [x] const char *GetClipboardText(void); # Implemented: `Clipboard.get` +- [x] void EnableEventWaiting(void); # Implemented: `Window.event_waiting` +- [x] void DisableEventWaiting(void); # Implemented: `Window.event_waiting` +- [x] void ShowCursor(void); # Implemented: `Window.Cursor.hidden` +- [x] void HideCursor(void); # Implemented: `Window.Cursor.hidden` +- [x] bool IsCursorHidden(void); # Implemented: `Window.Cursor.hidden` +- [x] void EnableCursor(void); # Implemented: `Window.Cursor.locked` +- [x] void DisableCursor(void); # Implemented: `Window.Cursor.locked` +- [x] bool IsCursorOnScreen(void); # Implemented: `Window.Cursor.on_screen` +- [x] void ClearBackground(Color color); # Implemented: `Window.clear_background` +- [x] void BeginDrawing(void); # Implemented: `Window.begin_drawing` and `Window.draw` +- [x] void EndDrawing(void); # Implemented: `Window.end_drawing` and `Window.draw` +- [x] void BeginMode2D(Camera2D camera); # Implemented: `Window.begin_2D` +- [x] void EndMode2D(void); # Implemented: `Window.end_2D` +- [ ] void BeginMode3D(Camera3D camera); +- [ ] void EndMode3D(void); +- [ ] void BeginTextureMode(RenderTexture2D target); +- [ ] void EndTextureMode(void); +- [ ] void BeginShaderMode(Shader shader); +- [ ] void EndShaderMode(void); +- [ ] void BeginBlendMode(int mode); +- [ ] void EndBlendMode(void); +- [x] void BeginScissorMode(int x, int y, int width, int height); # Implemented: `Window.begin_scissor` & `Window.scissor` +- [x] void EndScissorMode(void); # Implemented: `Window.begin_scissor` & `Window.scissor` +- [ ] void BeginVrStereoMode(VrStereoConfig config); +- [ ] void EndVrStereoMode(void); +- [ ] VrStereoConfig LoadVrStereoConfig(VrDeviceInfo device); +- [ ] void UnloadVrStereoConfig(VrStereoConfig config); +- [ ] Shader LoadShader(const char *vsFileName, const char *fsFileName); +- [ ] Shader LoadShaderFromMemory(const char *vsCode, const char *fsCode); +- [ ] bool IsShaderReady(Shader shader); +- [ ] int GetShaderLocation(Shader shader, const char *uniformName); +- [ ] int GetShaderLocationAttrib(Shader shader, const char *attribName); +- [ ] void SetShaderValue(Shader shader, int locIndex, const void *value, int uniformType); +- [ ] void SetShaderValueV(Shader shader, int locIndex, const void *value, int uniformType, int count); +- [ ] void SetShaderValueMatrix(Shader shader, int locIndex, Matrix mat); +- [ ] void SetShaderValueTexture(Shader shader, int locIndex, Texture2D texture); +- [ ] void UnloadShader(Shader shader); +- [ ] Ray GetMouseRay(Vector2 mousePosition, Camera camera); +- [ ] Matrix GetCameraMatrix(Camera camera); +- [ ] Matrix GetCameraMatrix2D(Camera2D camera); +- [ ] Vector2 GetWorldToScreen(Vector3 position, Camera camera); +- [ ] Vector2 GetScreenToWorld2D(Vector2 position, Camera2D camera); +- [ ] Vector2 GetWorldToScreenEx(Vector3 position, Camera camera, int width, int height); +- [ ] Vector2 GetWorldToScreen2D(Vector2 position, Camera2D camera); +- [x] void SetTargetFPS(int fps); # Implemented: `Window.target_fps` +- [x] float GetFrameTime(void); # Implemented: `Window.frame_time` +- [x] double GetTime(void); # Implemented: `Window.time` +- [x] int GetFPS(void); # Implemented: `Window.fps` +- [ ] void SwapScreenBuffer(void); +- [ ] void PollInputEvents(void); +- ❌ void WaitTime(double seconds); # Unneeded: Built-in to GLib `Thread.usleep` +- ❌ void SetRandomSeed(unsigned int seed); # Unneeded: Built-in to GLib `GLib.Random` +- ❌ int GetRandomValue(int min, int max); # Unneeded: Built-in to GLib `GLib.Random` +- ❌ int *LoadRandomSequence(unsigned int count, int min, int max); # Unneeded: Built-in to GLib `GLib.Random` +- ❌ void UnloadRandomSequence(int *sequence); # Unneeded: Built-in to GLib `GLib.Random` +- [x] void TakeScreenshot(const char *fileName); # Implemented: `Window.take_screenshot` +- [ ] void SetConfigFlags(unsigned int flags); +- ❌ void OpenURL(const char *url); # Unneeded: Built-in to GLib `GLib.AppInfo` and `GLib.AppLaunchContext` +- ❌ void TraceLog(int logLevel, const char *text, ...); # Unneeded: Builtin `GLib Log Functions` +- ❌ void SetTraceLogLevel(int logLevel); # Unneeded: Builtin `GLib Log Functions` +- ❌ void *MemAlloc(unsigned int size); # Unneeded: Built-in to GLib `GLib.malloc` +- ❌ void *MemRealloc(void *ptr, unsigned int size); # Unneeded: Built-in to GLib `GLib.realloc` +- ❌ void MemFree(void *ptr); # Unneeded: Built-in to GLib `GLib.free` +- ❌ void SetTraceLogCallback(TraceLogCallback callback); # Unneeded: Builtin `GLib Log Functions` +- ❌ void SetLoadFileDataCallback(LoadFileDataCallback callback); # Unneeded: Builtin `GLib Log Functions` +- ❌ void SetSaveFileDataCallback(SaveFileDataCallback callback); # Unneeded: Builtin `GLib Log Functions` +- ❌ void SetLoadFileTextCallback(LoadFileTextCallback callback); # Unneeded: Builtin `GLib Log Functions` +- ❌ void SetSaveFileTextCallback(SaveFileTextCallback callback); # Unneeded: Builtin `GLib Log Functions` +- ❌ unsigned char *LoadFileData(const char *fileName, int *dataSize); # Unneeded: Builtin `GLib File Functions` +- ❌ void UnloadFileData(unsigned char *data); # Unneeded: See above. +- ❌ bool SaveFileData(const char *fileName, void *data, int dataSize); # Unneeded: See above. +- ❌ bool ExportDataAsCode(const unsigned char *data, int dataSize, const char *fileName); # Unneeded: See above. +- ❌ char *LoadFileText(const char *fileName); # Unneeded: See above. +- ❌ void UnloadFileText(char *text); # Unneeded: See above. +- ❌ bool SaveFileText(const char *fileName, char *text); # Unneeded: See above. +- ❌ bool FileExists(const char *fileName); # Unneeded: See above. +- ❌ bool DirectoryExists(const char *dirPath); # Unneeded: See above. +- ❌ bool IsFileExtension(const char *fileName, const char *ext); # Unneeded: See above. +- ❌ int GetFileLength(const char *fileName); # Unneeded: See above. +- ❌ const char *GetFileExtension(const char *fileName); # Unneeded: See Above. +- ❌ const char *GetFileName(const char *filePath); # Unneeded: See Above. +- ❌ const char *GetFileNameWithoutExt(const char *filePath); # Unneeded: See Above. +- ❌ const char *GetDirectoryPath(const char *filePath); # Unneeded: See Above. +- ❌ const char *GetPrevDirectoryPath(const char *dirPath); # Unneeded: See Above. +- ❌ const char *GetWorkingDirectory(void); # Unneeded: Builtin `GLib.Environment.get_current_dir` +- ❌ const char *GetApplicationDirectory(void); # Unneeded: Builtin `GLib File Functions` +- ❌ bool ChangeDirectory(const char *dir); # Unneeded: Builtin `GLib.Environment.set_current_dir` +- ❌ bool IsPathFile(const char *path); +- ❌ FilePathList LoadDirectoryFiles(const char *dirPath); # Unneeded: Builtin `GLib.Dir` +- ❌ FilePathList LoadDirectoryFilesEx(const char *basePath, const char *filter, bool scanSubdirs); # Unneeded: Builtin `GLib.Dir` +- ❌ void UnloadDirectoryFiles(FilePathList files); # Unneeded: Builtin `GLib.Dir` +- [x] bool IsFileDropped(void); # Implemented: `Window.file_dropped` +- [x] FilePathList LoadDroppedFiles(void); # Implemented: `Window.get_dropped_files` +- [x] void UnloadDroppedFiles(FilePathList files); # Implemented: `Window.get_dropped_files` +- ❌ long GetFileModTime(const char *fileName); # Unneeded: Builtin `GLib.FileInfo.get_modification_date_time` +- ❌ unsigned char *CompressData(const unsigned char *data, int dataSize, int *compDataSize); # Unneeded: Built into GLib `GLib.ZlibCompressor` +- ❌ unsigned char *DecompressData(const unsigned char *compData, int compDataSize, int *dataSize); # Unneeded: Built into GLib `GLib.ZlibDecompressor` +- ❌ char *EncodeDataBase64(const unsigned char *data, int dataSize, int *outputSize); # Unneeded: Built into GLib. `GLib.Base64.encode` +- ❌ unsigned char *DecodeDataBase64(const unsigned char *data, int *outputSize); # Unneeded: Built into GLib. `GLib.Base64.decode` +- [x] AutomationEventList LoadAutomationEventList(const char *fileName); # Implemented: `Automation.EventList` +- [x] void UnloadAutomationEventList(AutomationEventList *list); # Implemented: `Automation.EventList` +- [x] bool ExportAutomationEventList(AutomationEventList list, const char *fileName); # Implemented: `Automation.EventList.export` +- [x] void SetAutomationEventList(AutomationEventList *list); # Implemented: `Automation.set_automation_event_list` +- [x] void SetAutomationEventBaseFrame(int frame); # Implemented: `Window.set_automation_event_base_frame` +- [x] void StartAutomationEventRecording(void); # Implemented: `Window.record_automation_events` +- [x] void StopAutomationEventRecording(void); # Implemented: `Window.record_automation_events` +- [x] void PlayAutomationEvent(AutomationEvent event); `Window.play_automation_event` +- [x] bool IsKeyPressed(int key); # Implemented: `Input.Keyboard.is_pressed` +- [x] bool IsKeyPressedRepeat(int key); # Implemented: `Input.Keyboard.is_pressed_repeat` +- [x] bool IsKeyDown(int key); # Implemented: `Input.Keyboard.is_down` +- [x] bool IsKeyReleased(int key); # Implemented: `Input.Keyboard.is_released` +- [x] bool IsKeyUp(int key); # Implemented: `Input.Keyboard.is_up` +- [x] int GetKeyPressed(void); # Implemented: `Input.Keyboard.key_pressed` +- [x] int GetCharPressed(void); # Implemented: `Input.Keyboard.char_pressed` +- [x] void SetExitKey(int key); # Implemented: `Window.exit_key` +- [x] bool IsGamepadAvailable(int gamepad); # Implemented: `Input.Gamepad.still_around` +- [x] const char *GetGamepadName(int gamepad); # Implemented `Input.Gamepad.name` +- [x] bool IsGamepadButtonPressed(int gamepad, int button); # Implemented: `Input.Gamepad.is_button_pressed` +- [x] bool IsGamepadButtonDown(int gamepad, int button); # Implemented: `Input.Gamepad.is_button_down` +- [x] bool IsGamepadButtonReleased(int gamepad, int button); # Implemented: `Input.Gamepad.is_button_released` +- [x] bool IsGamepadButtonUp(int gamepad, int button); # Implemented: `Input.Gamepad.is_button_up` +- [x] int GetGamepadButtonPressed(void); # Implemented: `Input.Gamepad.button_pressed` +- [x] int GetGamepadAxisCount(int gamepad); # Implemented: `Input.Gamepad.axis_count` +- [x] float GetGamepadAxisMovement(int gamepad, int axis); # Implemented: `Input.Gamepad.get_axis_movement` +- [x] int SetGamepadMappings(const char *mappings); # Implemented: `Input.Gamepad.set_mappings` +- [x] bool IsMouseButtonPressed(int button); # Implemented: `Input.Mouse.is_pressed` +- [x] bool IsMouseButtonDown(int button); # Implemented: `Input.Mouse.is_down` +- [x] bool IsMouseButtonReleased(int button); # Implemented: `Input.Mouse.is_released` +- [x] bool IsMouseButtonUp(int button); # Implemented: `Input.Mouse.is_up` +- [x] int GetMouseX(void); # Implemented: `Input.Mouse.x` +- [x] int GetMouseY(void); # Implemented: `Input.Mouse.y` +- [x] Vector2 GetMousePosition(void); # Implemented: `Input.Mouse.position` +- [x] Vector2 GetMouseDelta(void); # Implemented: `Input.Mouse.delta` +- [x] void SetMousePosition(int x, int y); # Implemented: `Input.Mouse.position` +- [x] void SetMouseOffset(int offsetX, int offsetY); # Implemented: `Input.Mouse.offset` +- [x] void SetMouseScale(float scaleX, float scaleY); # Implemented: `Input.Mouse.scale` +- [x] float GetMouseWheelMove(void); # Implemented: `Input.Mouse.wheel_move` +- [x] Vector2 GetMouseWheelMoveV(void); # Implemented: `Input.Mouse.wheel_move` +- [x] void SetMouseCursor(int cursor); # Implemented: `Input.Mouse.set_cursor` +- [x] int GetTouchX(void); # Implemented: `Input.Touch.x` +- [x] int GetTouchY(void); # Implemented: `Input.Touch.y` +- [x] Vector2 GetTouchPosition(int index); # Implemented: `Input.Touch.get_position` +- [x] int GetTouchPointId(int index); # Implemented: `Input.Touch.get_id` +- [x] int GetTouchPointCount(void); # Implemented: `Input.Touch.point_count` +- [x] void SetGesturesEnabled(unsigned int flags); # Implemented: `Input.Touch.enable_gestures` +- [x] bool IsGestureDetected(unsigned int gesture); # Implemented: `Input.Touch.is_gesture_detected` +- [x] int GetGestureDetected(void); # Implemented: `Input.Touch.detected_gesture` +- [x] float GetGestureHoldDuration(void); # Implemented: `Input.Touch.hold_duration` +- [x] Vector2 GetGestureDragVector(void); # Implemented: `Input.Touch.drag_vector` +- [x] float GetGestureDragAngle(void); # Implemented: `Input.Touch.drag_angle` +- [x] Vector2 GetGesturePinchVector(void); # Implemented: `Input.Touch.pinch_vector` +- [x] float GetGesturePinchAngle(void); # Implemented: `Input.Touch.pinch_angle` +- [ ] void UpdateCamera(Camera *camera, int mode); +- [ ] void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom); diff --git a/src/utils/bin2vala.vala b/src/utils/bin2vala.vala new file mode 100644 index 0000000..26ef2b3 --- /dev/null +++ b/src/utils/bin2vala.vala @@ -0,0 +1,86 @@ +/* This script creates a constant uint8 array of any file, for use with embedding + * into code. + * If you want to use it, just run: valac bin2vala.vala and run the output. + */ +using GLib; + +public class Main : GLib.Object { + private static string? outputFile = null; + private static string? inputFile = null; + private static string? namespace = null; + private static string? variable = null; + private const OptionEntry[] opts = { + {"input", 'i', OptionFlags.NONE, OptionArg.FILENAME, ref inputFile, "Input file", "file"}, + {"output", 'o', OptionFlags.NONE, OptionArg.FILENAME, ref outputFile, "Output file, defaults to standard output.", "file"}, + {"namespace", 'n', OptionFlags.NONE, OptionArg.STRING, ref namespace, "Namespace (Optional)", "string"}, + {"variable", 'v', OptionFlags.NONE, OptionArg.STRING, ref variable, "Variable Name", "string"}, + {null} + }; + static int main(string[] args) { + try { + var options = new OptionContext("- bin2vala Options"); + options.set_help_enabled(true); + options.add_main_entries(opts, null); + options.parse(ref args); + } catch(OptionError e) { + error(@"Error: $(e.message)"); + } + /* Check if user provided everything */ + if(inputFile == null) { + error("No input file provided."); + } + FileStream o; + if(outputFile == null) { + var fd = stdout.fileno(); + o = FileStream.fdopen(fd, "w"); + } else { + o = FileStream.open(outputFile, "w"); + } + if(variable == null) { + error("Variable name not provided."); + } + + /* Print Namespace */ + if(namespace != null) { + o.printf("namespace %s {\n\t", namespace); + } + o.printf("const uint8[] %s = {\n\t", variable); + if(namespace != null) { + o.putc('\t'); + } + /* Get bytes from input file */ + var i = FileStream.open(inputFile, "rb"); + /* Get size of input file */ + i.seek(0, FileSeek.END); + int64 size = i.tell(); + i.rewind(); + /* Get bytes from file */ + uint8[] inputBuf = new uint8[size]; + var read = i.read(inputBuf); + /* Make sure the size read was correct */ + assert(size == read); + int c = 0; + foreach (uint8 b in inputBuf) { + /* Make sure we line break every 80 characters */ + if(c >= 80) { + o.printf("\n\t"); + if(namespace != null) { + o.printf("\t"); + } + c = 0; + } + c += 5; + /* Print out hexidecimal */ + o.printf("%03d, ", b); + } + o.putc('\n'); + if(namespace != null) { + o.putc('\t'); + } + o.printf("};\n"); + if(namespace != null) { + o.printf("}\n"); + } + return(0); + } +} diff --git a/subprojects/raylib/bunnymark/main.c b/subprojects/raylib/bunnymark/main.c new file mode 100644 index 0000000..fa45d9d --- /dev/null +++ b/subprojects/raylib/bunnymark/main.c @@ -0,0 +1,125 @@ +/******************************************************************************************* +* +* raylib [textures] example - Bunnymark +* +* Example originally created with raylib 1.6, 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 +* +* Copyright (c) 2014-2023 Ramon Santamaria (@raysan5) +* +********************************************************************************************/ + +#include "raylib.h" + +#include // Required for: malloc(), free() + +#define MAX_BUNNIES 5000000 // 50K bunnies limit + +// This is the maximum amount of elements (quads) per batch +// NOTE: This value is defined in [rlgl] module and can be changed there +#define MAX_BATCH_ELEMENTS 8192 + +typedef struct Bunny { + Vector2 position; + Vector2 speed; + Color color; +} Bunny; + +//------------------------------------------------------------------------------------ +// Program main entry point +//------------------------------------------------------------------------------------ +int main(void) +{ + // Initialization + //-------------------------------------------------------------------------------------- + const int screenWidth = 800; + const int screenHeight = 450; + + InitWindow(screenWidth, screenHeight, "raylib [textures] example - bunnymark"); + + // Load bunny texture + Texture2D texBunny = LoadTexture("resources/wabbit_alpha.png"); + + Bunny *bunnies = (Bunny *)malloc(MAX_BUNNIES*sizeof(Bunny)); // Bunnies array + + int bunniesCount = 0; // Bunnies counter + + SetTargetFPS(9999); // Set our game to run at 60 frames-per-second + //-------------------------------------------------------------------------------------- + + // Main game loop + while (!WindowShouldClose()) // Detect window close button or ESC key + { + // Update + //---------------------------------------------------------------------------------- + if (IsMouseButtonDown(MOUSE_BUTTON_LEFT)) + { + // Create more bunnies + for (int i = 0; i < 100; i++) + { + if (bunniesCount < MAX_BUNNIES) + { + bunnies[bunniesCount].position = GetMousePosition(); + bunnies[bunniesCount].speed.x = (float)GetRandomValue(-250, 250)/60.0f; + bunnies[bunniesCount].speed.y = (float)GetRandomValue(-250, 250)/60.0f; + bunnies[bunniesCount].color = (Color){ GetRandomValue(50, 240), + GetRandomValue(80, 240), + GetRandomValue(100, 240), 255 }; + bunniesCount++; + } + } + } + + // Update bunnies + for (int i = 0; i < bunniesCount; i++) + { + bunnies[i].position.x += bunnies[i].speed.x; + bunnies[i].position.y += bunnies[i].speed.y; + + if (((bunnies[i].position.x + texBunny.width/2) > GetScreenWidth()) || + ((bunnies[i].position.x + texBunny.width/2) < 0)) bunnies[i].speed.x *= -1; + if (((bunnies[i].position.y + texBunny.height/2) > GetScreenHeight()) || + ((bunnies[i].position.y + texBunny.height/2 - 40) < 0)) bunnies[i].speed.y *= -1; + } + //---------------------------------------------------------------------------------- + + // Draw + //---------------------------------------------------------------------------------- + BeginDrawing(); + + ClearBackground(RAYWHITE); + + for (int i = 0; i < bunniesCount; i++) + { + // NOTE: When internal batch buffer limit is reached (MAX_BATCH_ELEMENTS), + // a draw call is launched and buffer starts being filled again; + // before issuing a draw call, updated vertex data from internal CPU buffer is send to GPU... + // Process of sending data is costly and it could happen that GPU data has not been completely + // processed for drawing while new data is tried to be sent (updating current in-use buffers) + // it could generates a stall and consequently a frame drop, limiting the number of drawn bunnies + DrawTexture(texBunny, (int)bunnies[i].position.x, (int)bunnies[i].position.y, bunnies[i].color); + } + + DrawRectangle(0, 0, screenWidth, 40, BLACK); + DrawText(TextFormat("bunnies: %i", bunniesCount), 120, 10, 20, GREEN); + DrawText(TextFormat("batched draw calls: %i", 1 + bunniesCount/MAX_BATCH_ELEMENTS), 320, 10, 20, MAROON); + + DrawFPS(10, 10); + + EndDrawing(); + //---------------------------------------------------------------------------------- + } + + // De-Initialization + //-------------------------------------------------------------------------------------- + free(bunnies); // Unload bunnies data array + + UnloadTexture(texBunny); // Unload bunny texture + + CloseWindow(); // Close window and OpenGL context + //-------------------------------------------------------------------------------------- + + return 0; +} diff --git a/subprojects/raylib/meson.build b/subprojects/raylib/meson.build new file mode 100644 index 0000000..ee66ed1 --- /dev/null +++ b/subprojects/raylib/meson.build @@ -0,0 +1,167 @@ +project( + 'raylib', + 'c', + version: '5.0.0', + default_options: [ + 'c_std=c99', + 'warning_level=1', + 'optimization=1' + ] +) + +pkg = import('pkgconfig') +cc = meson.get_compiler('c') +version = meson.project_version() +os = build_machine.system() + +# Debug stuff. +# Doing this because the debug defaults for Meson are really bad. +# More debug symbols. +if cc.has_argument('-g3') == true + add_project_arguments('-g3', language: 'c') +elif cc.has_argument('-g') == true + add_project_arguments('-g', language: 'c') +endif +if cc.has_argument('-ggdb3') == true + add_project_arguments('-ggdb3', language: 'c') +elif cc.has_argument('-ggdb') == true + add_project_arguments('-ggdb', language: 'c') +endif +# Compress debug symbols if possible. +if cc.has_link_argument('-Wl,--compress-debug-sections=zstd') == true + add_project_link_arguments( + '-Wl,--compress-debug-sections=zstd', + language: 'c' + ) +elif cc.has_link_argument('-Wl,--compress-debug-sections=zlib') == true + add_project_link_arguments( + '-Wl,--compress-debug-sections=zlib', + language: 'c' + ) +endif + +deps = [] + +if os == 'windows' + deps += [ + cc.find_library('winmm', required: true), + cc.find_library('opengl32', required: true), + cc.find_library('shell32', required: true), + cc.find_library('gdi32', required: true), + ] +elif os == 'darwin' + deps += [ + dependency('OpenGL'), + dependency('Cocoa'), + dependency('IOKit'), + dependency('CoreAudio'), + dependency('CoreVideo'), + ] +else + deps += [ + dependency('threads'), + cc.find_library('m', required: false), + cc.find_library('dl', required: false), + cc.find_library('rt', required: false), + ] +endif + +src = [ + 'source/src/rcore.c', + 'source/src/rmodels.c', + 'source/src/rshapes.c', + 'source/src/rtext.c', + 'source/src/rtextures.c', + 'source/src/utils.c', + 'source/src/raudio.c', +] +c_args = [] +inc_dirs = ['source/src'] +graphics_option = get_option('gl_api') +if graphics_option == '1.1' + c_args += '-DGRAPHICS_API_OPENGL_11' +elif graphics_option == '2.1' + c_args += '-DGRAPHICS_API_OPENGL_21' +elif graphics_option == '3.3' + c_args += '-DGRAPHICS_API_OPENGL_33' +elif graphics_option == '4.3' + c_args += '-DGRAPHICS_API_OPENGL_43' +elif graphics_option == 'es2' + c_args += '-DGRAPHICS_API_OPENGL_ES2' +elif graphics_option == 'es3' + c_args += '-DGRAPHICS_API_OPENGL_ES3' +endif + +platform = get_option('platform') +if platform == 'desktop' + c_args += '-DPLATFORM_DESKTOP' + if get_option('native_glfw') == true + deps += dependency('glfw3', required: true) + else + inc_dirs += [ + 'source/src/external/glfw/include', + 'source/src/external/glfw/deps/mingw' + ] + src += 'source/src/rglfw.c' + if os != 'windows' and os != 'darwin' + deps += [ + dependency('gl'), + dependency('x11'), + dependency('xcursor'), + dependency('xrandr'), + dependency('xinerama'), + dependency('xi'), + ] + endif + endif +elif platform == 'desktop_sdl' + c_args += '-DPLATFORM_DESKTOP_SDL' + deps += dependency('SDL2', required: true) +elif platform == 'drm' + c_args += '-DPLATFORM_DRM' + if graphics_option != 'es2' + error('es2 must be selected as the gl_api when using drm platform. Pass -Dgl_api=es2 to meson.') + endif + deps += dependency('libdrm', required: true) + deps += dependency('gbm', required: true) + deps += dependency('egl', required: true) + deps += dependency('gl', required: true) +endif +# Required defines +c_args += [ + '-DSUPPORT_FILEFORMAT_WAV', + '-DSUPPORT_FILEFORMAT_OGG', + '-DSUPPORT_FILEFORMAT_MP3', + '-DSUPPORT_FILEFORMAT_QOA', + '-DSUPPORT_FILEFORMAT_FLAC', + '-DSUPPORT_FILEFORMAT_XM', + '-DSUPPORT_FILEFORMAT_MOD', + '-DBUILD_LIBTYPE_SHARED', + '-D_GNU_SOURCE', + '-Wno-missing-braces', + '-Werror=pointer-arith', + '-Werror=implicit-function-declaration', + '-fno-strict-aliasing', + '-Wno-unused-function', +] +add_project_arguments(c_args, language: 'c') +incdir = include_directories(inc_dirs) + +lib = static_library( + 'raylib', + sources: src, + dependencies: deps, + include_directories: incdir +) + +raylib_dep = declare_dependency( + link_with: lib, + include_directories: incdir, +) + +# For testing if the library built correctly. +raylib_exe = executable( + 'bunnymark', + sources: 'bunnymark/main.c', + dependencies: raylib_dep, +) diff --git a/subprojects/raylib/meson_options.txt b/subprojects/raylib/meson_options.txt new file mode 100644 index 0000000..27ab90f --- /dev/null +++ b/subprojects/raylib/meson_options.txt @@ -0,0 +1,5 @@ +# Only valid if platform is set to 'desktop' +option('native_glfw', type: 'boolean', value: false) + +option('gl_api', type: 'combo', choices: ['1.1', '2.1', '3.3', '4.3', 'es2', 'es3'], value: '3.3') +option('platform', type: 'combo', choices: ['desktop', 'desktop_sdl', 'drm'], value: 'desktop') diff --git a/subprojects/raylib/resources b/subprojects/raylib/resources new file mode 120000 index 0000000..8299958 --- /dev/null +++ b/subprojects/raylib/resources @@ -0,0 +1 @@ +source/examples/textures/resources/ \ No newline at end of file diff --git a/subprojects/raylib/source b/subprojects/raylib/source new file mode 160000 index 0000000..ae50bfa --- /dev/null +++ b/subprojects/raylib/source @@ -0,0 +1 @@ +Subproject commit ae50bfa2cc569c0f8d5bc4315d39db64005b1b08 diff --git a/vapi/raylib.vapi b/vapi/raylib.vapi index eeaab76..dd47d81 100644 --- a/vapi/raylib.vapi +++ b/vapi/raylib.vapi @@ -184,7 +184,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "Image")] + [CCode (cname = "Image", free_function = "UnloadImage")] public struct Image { void* data; @@ -207,7 +207,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "Texture2D")] + [CCode (cname = "Texture2D", free_function = "UnloadTexture")] public struct Texture2D { public uint id; // OpenGL texture id public int width; // Texture base width @@ -238,7 +238,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "RenderTexture2D")] + [CCode (cname = "RenderTexture2D", free_function = "UnloadRenderTexture")] public struct RenderTexture2D : RenderTexture { public uint id; // OpenGL framebuffer object id @@ -270,7 +270,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "Font")] + [CCode (cname = "Font", free_function = "UnloadFont")] public struct Font { public int baseSize; // Base size (default chars height) // vala-lint=naming-convention public int glyphCount; // Number of glyph characters // vala-lint=naming-convention @@ -314,7 +314,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "Mesh")] + [CCode (cname = "Mesh", free_function = "UnloadMesh")] public struct Mesh { public int vertexCount; // Number of vertices stored in arrays // vala-lint=naming-convention public int triangleCount; // Number of triangles stored (indexed or not) // vala-lint=naming-convention @@ -340,7 +340,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "Shader")] + [CCode (cname = "Shader", free_function = "UnloadShader")] public struct Shader { public uint id; // Shader program id public unowned int[] locs; // Shader locations array (RL_MAX_SHADER_LOCATIONS) @@ -356,7 +356,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "Material")] + [CCode (cname = "Material", free_function = "UnloadMaterial")] public struct Material { unowned Shader shader; // Material shader unowned MaterialMap[] maps; // Material maps array (MAX_MATERIAL_MAPS) @@ -379,7 +379,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "Model")] + [CCode (cname = "Model", free_function = "UnloadModel")] public struct Model { public Matrix transform; // Local transform matrix @@ -396,7 +396,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "ModelAnimation")] + [CCode (cname = "ModelAnimation", free_function = "UnloadModelAnimation")] public struct ModelAnimation { public int boneCount; // Number of bones // vala-lint=naming-convention public int frameCount; // Number of animation frames // vala-lint=naming-convention @@ -428,7 +428,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "Wave")] + [CCode (cname = "Wave", free_function = "UnloadWave")] public struct Wave { public uint frameCount; // Total number of frames (considering channels) // vala-lint=naming-convention public uint sampleRate; // Frequency (samples per second) // vala-lint=naming-convention @@ -446,7 +446,7 @@ namespace Raylib { public struct AudioProcessor { } [SimpleType] - [CCode (cname = "AudioStream")] + [CCode (cname = "AudioStream", free_function = "UnloadAudioStream")] public struct AudioStream { public AudioBuffer buffer; // Pointer to internal data used by the audio system public AudioProcessor processor; // Pointer to internal data processor, useful for audio effects @@ -457,14 +457,14 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "Sound")] + [CCode (cname = "Sound", free_function = "UnloadSound")] public struct Sound { public AudioStream stream; // Audio stream public uint frameCount; // Total number of frames (considering channels) // vala-lint=naming-convention } [SimpleType] - [CCode (cname = "Music")] + [CCode (cname = "Music", free_function = "UnloadMusicStream")] public struct Music { public AudioStream stream; // Audio stream public uint frameCount; // Total number of frames (considering channels) // vala-lint=naming-convention @@ -490,7 +490,7 @@ namespace Raylib { } [SimpleType] - [CCode (cname = "VrStereoConfig")] + [CCode (cname = "VrStereoConfig", free_function = "UnloadVrStereoConfig")] public struct VrStereoConfig { public Matrix projection[2]; // VR projection matrices (per eye) public Matrix viewOffset[2]; // VR view offset matrices (per eye) // vala-lint=naming-convention @@ -507,6 +507,7 @@ namespace Raylib { public struct FilePathList { public uint capacity; // Filepaths max entries public uint count; // Filepaths entries count + [CCode (array_length_cname = "count", array_length_type = "unsigned int")] public unowned string[] paths; // Filepaths entries } @@ -526,6 +527,7 @@ namespace Raylib { WINDOW_TRANSPARENT, // Set to allow transparent framebuffer WINDOW_HIGHDPI, // Set to support HighDPI WINDOW_MOUSE_PASSTHROUGH, // Set to support mouse passthrough, only supported when FLAG_WINDOW_UNDECORATED + BORDERLESS_WINDOWED_MODE, // Set to run program in borderless windowed mode MSAA_4X_HINT, // Set to try enabling MSAA 4X INTERLACED_HINT // Set to try enabling interlaced video format (for V3D) } @@ -866,8 +868,8 @@ namespace Raylib { // Callbacks to hook some internal functions // WARNING: This callbacks are intended for advance users - [CCode (cname = "TraceLogCallback")] - public delegate void TraceLogCallback (TraceLogLevel log_level, string text, va_list args); + [CCode (cname = "TraceLogCallback", has_target = false)] + public delegate void TraceLogCallback (int log_level, string text, va_list args); [CCode (cname = "LoadFileDataCallback")] public delegate uchar LoadFileDataCallback (string filename, out int bytes_read); @@ -955,6 +957,9 @@ namespace Raylib { [CCode (cname = "SetWindowMinSize")] public static void set_window_minimum_size (int width, int height); + [CCode (cname = "SetWindowMaxSize")] + public static void set_window_maximum_size (int width, int height); + [CCode (cname = "SetWindowSize")] public static void set_window_size (int width, int height); @@ -995,7 +1000,7 @@ namespace Raylib { public static int get_monitor_width (int monitor); [CCode (cname = "GetMonitorHeight")] - public static int get_hmonitor_eight (int monitor); + public static int get_monitor_height (int monitor); [CCode (cname = "GetMonitorPhysicalWidth")] public static int get_monitor_physical_width (int monitor); @@ -1300,7 +1305,7 @@ namespace Raylib { [CCode (cname = "IsFileDropped")] public static bool is_file_dropped (); - [CCode (cname = "FilePathList")] + [CCode (cname = "LoadDroppedFiles")] public static FilePathList load_dropped_files (); [CCode (cname = "UnloadDroppedFiles")] @@ -1322,28 +1327,74 @@ namespace Raylib { [CCode (cname = "DecodeDataBase64")] public static uchar[] decode_data_base64 (uchar[] data, out int size); + //------------------------------------------------------------------------------------ + // Automation + //------------------------------------------------------------------------------------ + [SimpleType] + [CCode (cname = "AutomationEvent")] + public struct AutomationEvent { + public uint frame; + public uint type; + public int params[4]; + } + + [SimpleType] + [CCode (cname = "AutomationEventList")] + public struct AutomationEventList { + public uint capacity; + public uint count; + AutomationEvent *events; + } + + [CCode (cname = "LoadAutomationEventList")] + public static AutomationEventList load_automation_event_list(string fileName); + + [CCode (cname = "UnloadAutomationEventList")] + public static void unload_automation_event_list(AutomationEventList *list); + + [CCode (cname = "ExportAutomationEventList")] + public static bool export_automation_event_list(AutomationEventList list, string fileName); + + [CCode (cname = "SetAutomationEventList")] + public static void set_automation_event_list(AutomationEventList *list); + + [CCode (cname = "SetAutomationEventBaseFrame")] + public static void set_automation_event_base_frame(int frame); + + [CCode (cname = "StartAutomationEventRecording")] + public static void start_automation_event_recording(); + + [CCode (cname = "StopAutomationEventRecording")] + public static void stop_automation_event_recording(); + + [CCode (cname = "PlayAutomationEvent")] + public static void play_automation_event(AutomationEvent event); + //------------------------------------------------------------------------------------ // Input Handling Functions (Module: core) //------------------------------------------------------------------------------------ // Input-related functions: keyboard [CCode (cname = "IsKeyPressed")] - public static bool is_key_pressed (KeyboardKey key); + public static bool is_key_pressed (int key); + + [CCode (cname = "IsKeyPressedRepeat")] + public static bool is_key_pressed_repeat (int key); [CCode (cname = "IsKeyDown")] - public static bool is_key_down (KeyboardKey key); + public static bool is_key_down (int key); [CCode (cname = "IsKeyReleased")] - public static bool is_key_released (KeyboardKey key); + public static bool is_key_released (int key); [CCode (cname = "IsKeyUp")] - public static bool is_key_up (KeyboardKey key); + public static bool is_key_up (int key); [CCode (cname = "SetExitKey")] - public static void set_exit_key (KeyboardKey key); + public static void set_exit_key (int key); [CCode (cname = "GetKeyPressed")] - public static KeyboardKey get_key_pressed (); + public static int get_key_pressed (); [CCode (cname = "GetCharPressed")] public static int get_char_pressed (); @@ -1381,16 +1432,16 @@ namespace Raylib { // Input-related functions: mouse [CCode (cname = "IsMouseButtonPressed")] - public static bool is_mouse_button_pressed (MouseButton button); + public static bool is_mouse_button_pressed (int button); [CCode (cname = "IsMouseButtonDown")] - public static bool is_mouse_button_down (MouseButton button); + public static bool is_mouse_button_down (int button); [CCode (cname = "IsMouseButtonReleased")] - public static bool is_mouse_button_released (MouseButton button); + public static bool is_mouse_button_released (int button); [CCode (cname = "IsMouseButtonUp")] - public static bool is_mouse_button_up (MouseButton button); + public static bool is_mouse_button_up (int button); [CCode (cname = "GetMouseX")] public static int get_mouse_x (); @@ -1420,7 +1471,7 @@ namespace Raylib { public static Vector2 get_mouse_wheel_move_vector (); [CCode (cname = "SetMouseCursor")] - public static void set_mouse_cursor (MouseCursor cursor); + public static void set_mouse_cursor (int cursor); // Input-related functions: touch [CCode (cname = "GetTouchX")] @@ -1441,20 +1492,20 @@ namespace Raylib { //------------------------------------------------------------------------------------ // Gestures and Touch Handling Functions (Module: rgestures) //------------------------------------------------------------------------------------ - [CCode (cname = "SetGestureEnabled")] - public static void set_gesture_enabled (Gesture flags); + [CCode (cname = "SetGesturesEnabled")] + public static void set_gestures_enabled (int flags); [CCode (cname = "IsGestureDetected")] - public static bool is_gesture_detected (Gesture gesture); + public static bool is_gesture_detected (int gesture); [CCode (cname = "GetGestureDetected")] - public static Gesture get_gesture_detected (); + public static int get_gesture_detected (); [CCode (cname = "GetGestureHoldDuration")] public static float get_gesture_hold_duration (); [CCode (cname = "GetGestureDragVector")] - public static Vector2 get_gesture_drag_duration (); + public static Vector2 get_gesture_drag_vector (); [CCode (cname = "GetGestureDragAngle")] public static float get_gesture_drag_angle (); @@ -1966,7 +2017,7 @@ namespace Raylib { public static Font load_font_from_image (Image image, Color key, int first_char); [CCode (cname = "LoadFontFromMemory")] - public static Font load_font_from_memory (string file_type, uchar file_data, int font_size, int[] font_characters); + public static Font load_font_from_memory (string file_type, uint8[] file_data, int font_size, int[] font_characters); [CCode (cname = "IsFontReady")] public static bool is_font_ready (Font font); @@ -2347,6 +2398,9 @@ namespace Raylib { [CCode (cname = "SetMasterVolume")] public static void set_master_volume (float volume); + [CCode (cname = "GetMasterVolume")] + public static float get_master_volume (); + // Wave/Sound loading/unloading functions [CCode (cname = "LoadWave")] public static Wave load_wave (string filename); @@ -2363,6 +2417,9 @@ namespace Raylib { [CCode (cname = "LoadSoundFromWave")] public static Sound load_sound_from_wave (Wave wave); + [CCode (cname = "LoadSoundAlias")] + public static Sound load_sound_alias (Sound source); + [CCode (cname = "IsSoundReady")] public static bool is_sound_ready (Sound sound); diff --git a/vapi/rini.vapi b/vapi/rini.vapi deleted file mode 100644 index dfdcb63..0000000 --- a/vapi/rini.vapi +++ /dev/null @@ -1,92 +0,0 @@ -[Version (experimental = true)] -[CCode (cprefix = "", cheader_filename = "rini.h")] -namespace Rini { - [CCode (cname = "RINI_VERSION")] - public const string VERSION; - - //---------------------------------------------------------------------------------- - // Defines and Macros - //---------------------------------------------------------------------------------- - [CCode (cname = "RINI_MAX_LINE_SIZE")] - public const int MAX_LINE_SIZE; - - [CCode (cname = "RINI_MAX_KEY_SIZE")] - public const int MAX_KEY_SIZE; - - [CCode (cname = "RINI_MAX_TEXT_SIZE")] - public const int MAX_TEXT_SIZE; - - [CCode (cname = "RINI_MAX_DESC_SIZE")] - public const int MAX_DESC_SIZE; - - [CCode (cname = "RINI_MAX_VALUE_CAPACITY")] - public const int MAX_VALUE_CAPACITY; - - [CCode (cname = "RINI_VALUE_DELIMITER")] - public const char VALUE_DELIMITER; - - [CCode (cname = "RINI_LINE_COMMENT_DELIMITER")] - public const char LINE_COMMENT_DELIMITER; - - [CCode (cname = "RINI_VALUE_COMMENTS_DELIMITER")] - public const char VALUE_COMMENTS_DELIMITER; - - [CCode (cname = "RINI_LINE_SECTION_DELIMITER")] - public const char LINE_SECTION_DELIMITER; - - - //---------------------------------------------------------------------------------- - // Types and Structures Definition - //---------------------------------------------------------------------------------- - [CCode (cname = "rini_config_value")] - public struct ConfigValue { - public char key[MAX_KEY_SIZE]; // Config value key identifier - public char text[MAX_TEXT_SIZE]; // Config value text - public char desc[MAX_DESC_SIZE]; // Config value description - } - - [CCode (cname = "rini_config")] - public struct RiniConfig { - public ConfigValue[] values; // Config values array - public uint count; // Config values count - public uint capacity; // Config values capacity - } - - - //------------------------------------------------------------------------------------ - // Functions declaration - //------------------------------------------------------------------------------------ - [CCode (cname = "rini_load_config")] - public static RiniConfig load_config (string filename); // Load config from file (*.ini) or create a new config object (pass NULL) - - [CCode (cname = "rini_unload_config")] - public static void unload_config (RiniConfig config); // Unload config data from memory - - [CCode (cname = "rini_save_config")] - public static void save_config (RiniConfig config, string filename, string header); // Save config to file, with custom header - - - [CCode (cname = "rini_get_config_value")] - public static int get_config_value (RiniConfig config, string key); // Get config value int for provided key, returns -1 if not found - - [CCode (cname = "rini_get_config_value_text")] - public static string get_config_value_text (RiniConfig config, string key); // Get config value text for provided key - - [CCode (cname = "rini_get_config_value_description")] - public static string get_config_value_description (RiniConfig config, string key); // Get config value description for provided key - - - // Set config value int/text and description for existing key or create a new entry - // NOTE: When setting a text value, if id does not exist, a new entry is automatically created - [CCode (cname = "rini_set_config_value")] - public static int set_config_value (RiniConfig config, string key, int value, string description); - - [CCode (cname = "rini_set_config_value_text")] - public static int set_config_value_text (RiniConfig config, string key, string text, string description); - - - // Set config value description for existing key - // WARNING: Key must exist to add description, if a description exists, it is updated - [CCode (cname = "rini_set_config_value_description")] - public static int set_config_value_description (RiniConfig config, string key, string description); -}