├── .editorconfig ├── .gitignore ├── Makefile ├── README.md ├── examples ├── assemblyscript │ ├── README.md │ ├── asconfig.json │ ├── package.json │ ├── src │ │ ├── main.ts │ │ └── raylib-wasm.ts │ └── tsconfig.json ├── c │ ├── Makefile │ └── src │ │ ├── main.c │ │ └── raylib-wasm.h └── zig │ ├── .gitignore │ ├── README.md │ ├── build.zig │ ├── src │ ├── main.zig │ └── raylib-wasm.zig │ └── www │ ├── index.html │ └── wasmtest.js └── runtimes └── wasi ├── CMakeLists.txt └── main.c /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | charset = utf-8 6 | end_of_line = lf 7 | indent_size = 4 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [Makefile] 12 | indent_style = tab 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | build 2 | node_modules 3 | package-lock.json 4 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | test: wasi c 2 | runtimes/wasi/build/raylib-wasm examples/c/build/cart.wasm 3 | 4 | c: 5 | $(MAKE) -C examples/c 6 | 7 | wasi: 8 | cmake -B runtimes/wasi/build -S runtimes/wasi 9 | $(MAKE) -C runtimes/wasi/build 10 | 11 | clean: 12 | rm -rf examples/c/build 13 | rm -rf runtimes/wasi/build 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # raylib-wasm 2 | 3 | Very much a Work-In-Progress. *raylib-wasm* is a [WebAssembly](https://en.wikipedia.org/wiki/WebAssembly) build of [raylib](https://www.raylib.com/) designed to allow using raylib directly through any language that compiles to WebAssembly. 4 | 5 | ## Dependencies 6 | 7 | - make 8 | - cmake 9 | - [wasi](https://github.com/WebAssembly/wasi-sdk) 10 | 11 | ## Development 12 | 13 | ``` bash 14 | make 15 | ``` 16 | -------------------------------------------------------------------------------- /examples/assemblyscript/README.md: -------------------------------------------------------------------------------- 1 | # raylib-wasm assemblyscript 2 | 3 | This doesn't work currently. 4 | -------------------------------------------------------------------------------- /examples/assemblyscript/asconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "entries": [ 3 | "./src/main" 4 | ], 5 | "options": { 6 | "outFile": "build/cart.wasm", 7 | "bindings": "build/cart.js", 8 | "textFile": "build/cart.wat", 9 | "runtime": "incremental", 10 | "noExportMemory": true, 11 | "initialMemory": 65536, 12 | "maximumMemory": 65536, 13 | "zeroFilledMemory": true, 14 | "use": [ 15 | "trace=" 16 | ] 17 | }, 18 | "targets": { 19 | "release": { 20 | "optimizeLevel": 0, 21 | "shrinkLevel": 0, 22 | "converge": false, 23 | "noAssert": true, 24 | "use": "abort=" 25 | }, 26 | 27 | "debug": { 28 | "debug": true 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /examples/assemblyscript/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "raylib-wasm-asssemblyscript", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "src/main.ts", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "build": "asc --exportRuntime --target release -Osize", 9 | "build:debug": "asc --exportRuntime --target debug" 10 | }, 11 | "author": "", 12 | "license": "MIT", 13 | "dependencies": { 14 | "assemblyscript": "^0.21.2" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /examples/assemblyscript/src/main.ts: -------------------------------------------------------------------------------- 1 | import { 2 | TraceLog, 3 | InitWindow, 4 | SetTargetFPS, 5 | BeginDrawing, 6 | ClearBackground, 7 | DrawText, 8 | EndDrawing, 9 | LOG_INFO, 10 | RAYWHITE, 11 | LIGHTGRAY 12 | } from "./raylib-wasm" 13 | 14 | export function Init() : void { 15 | InitWindow(800, 450, "raylib-wasm") 16 | // SetTargetFPS(60) 17 | } 18 | 19 | export function UpdateDrawFrame() : void { 20 | BeginDrawing() 21 | ClearBackground(RAYWHITE) 22 | DrawText("Congrats! You created your first raylib-wasm assemblyscript window!", 50, 200, 20, LIGHTGRAY) 23 | EndDrawing() 24 | } 25 | 26 | export function Close() : void { 27 | TraceLog(LOG_INFO, "BYE!") 28 | } 29 | -------------------------------------------------------------------------------- /examples/assemblyscript/src/raylib-wasm.ts: -------------------------------------------------------------------------------- 1 | 2 | // Color, 4 components, R8G8B8A8 (32bit) 3 | export class Color { 4 | r: u8 5 | g: u8 6 | b: u8 7 | a: u8 8 | 9 | constructor(r:u8, g:u8, b:u8, a:u8 = 255) { 10 | this.r = r 11 | this.g = g 12 | this.b = b 13 | this.a = a 14 | } 15 | } 16 | 17 | export const LIGHTGRAY: Color = new Color(200, 200, 200, 255) // Light Gray 18 | export const GRAY : Color = new Color(130, 130, 130, 255) // Gray 19 | export const DARKGRAY : Color = new Color(80, 80, 80, 255) // Dark Gray 20 | export const YELLOW : Color = new Color(253, 249, 0, 255) // Yellow 21 | export const GOLD : Color = new Color(255, 203, 0, 255) // Gold 22 | export const ORANGE : Color = new Color(255, 161, 0, 255) // Orange 23 | export const PINK : Color = new Color(255, 109, 194, 255) // Pink 24 | export const RED : Color = new Color(230, 41, 55, 255) // Red 25 | export const MAROON : Color = new Color(190, 33, 55, 255) // Maroon 26 | export const GREEN : Color = new Color(0, 228, 48, 255) // Green 27 | export const LIME : Color = new Color(0, 158, 47, 255) // Lime 28 | export const DARKGREEN: Color = new Color(0, 117, 44, 255) // Dark Green 29 | export const SKYBLUE : Color = new Color(102, 191, 255, 255) // Sky Blue 30 | export const BLUE : Color = new Color(0, 121, 241, 255) // Blue 31 | export const DARKBLUE : Color = new Color(0, 82, 172, 255) // Dark Blue 32 | export const PURPLE : Color = new Color(200, 122, 255, 255) // Purple 33 | export const VIOLET : Color = new Color(135, 60, 190, 255) // Violet 34 | export const DARKPURPLE : Color = new Color(112, 31, 126, 255) // Dark Purple 35 | export const BEIGE : Color = new Color(211, 176, 131, 255) // Beige 36 | export const BROWN : Color = new Color(127, 106, 79, 255) // Brown 37 | export const DARKBROWN: Color = new Color(76, 63, 47, 255) // Dark Brown 38 | 39 | export const WHITE : Color = new Color(255, 255, 255, 255) // White 40 | export const BLACK : Color = new Color(0, 0, 0, 255) // Black 41 | export const BLANK : Color = new Color(0, 0, 0, 0) // Blank (Transparent) 42 | export const MAGENTA : Color = new Color(255, 0, 255, 255) // Magenta 43 | export const RAYWHITE : Color = new Color(245, 245, 245, 255) // My own White (raylib logo) 44 | 45 | /* 46 | 47 | WASM_EXPORT("Init") 48 | void Init(); 49 | 50 | WASM_EXPORT("UpdateDrawFrame") 51 | void UpdateDrawFrame(); 52 | 53 | WASM_EXPORT("Close") 54 | void Close(); 55 | 56 | WASM_IMPORT("InitWindow") 57 | void InitWindow(int width, int height, const char *title); 58 | 59 | WASM_IMPORT("BeginDrawing") 60 | void BeginDrawing(); 61 | 62 | WASM_IMPORT("ClearBackgroundExpanded") 63 | void ClearBackgroundExpanded(uint8_t r, uint8_t g, uint8_t b, uint8_t a); 64 | 65 | WASM_IMPORT("DrawTextExpanded") 66 | void DrawTextExpanded(const char *text, int posX, int posY, int fontSize, uint8_t r, uint8_t g, uint8_t b, uint8_t a); 67 | 68 | WASM_IMPORT("ClearBackground") 69 | void ClearBackground(Color color); 70 | 71 | WASM_IMPORT("SetTargetFPS") 72 | void SetTargetFPS(int fps); 73 | 74 | WASM_IMPORT("EndDrawing") 75 | void EndDrawing(); 76 | 77 | WASM_IMPORT("CloseWindow") 78 | void CloseWindow(); 79 | 80 | WASM_IMPORT("TraceLog") 81 | void TraceLog(int logLevel, const char* text); 82 | 83 | // Function wrappers 84 | void ClearBackground(Color color); 85 | void DrawText(const char* text, int posX, int posY, int fontSize, Color color); 86 | 87 | #ifdef RAYLIB_WASM_IMPLEMENTATION 88 | #ifndef RAYLIB_WASM_IMPLEMENTATION_ONCE 89 | #define RAYLIB_WASM_IMPLEMENTATION_ONCE 90 | 91 | void ClearBackground(Color color) { 92 | ClearBackgroundExpanded(color.r, color.g, color.b, color.a); 93 | } 94 | 95 | void DrawText(const char* text, int posX, int posY, int fontSize, Color color) { 96 | DrawTextExpanded(text, posX, posY, fontSize, color.r, color.g, color.b, color.a); 97 | } 98 | 99 | #endif // RAYLIB_WASM_IMPLEMENTATION_ONCE 100 | #endif // RAYLIB_WASM_IMPLEMENTATION 101 | 102 | #endif // RAYLIB_WASM 103 | */ 104 | 105 | export const LOG_ALL = 0 106 | export const LOG_TRACE = 1 107 | export const LOG_DEBUG = 2 108 | export const LOG_INFO = 3 109 | export const LOG_WARNING = 4 110 | export const LOG_ERROR = 5 111 | export const LOG_FATAL = 6 112 | export const LOG_NONE = 7 113 | 114 | @external("env", "SetTargetFPS") 115 | export declare function SetTargetFPS(fps: i32) :void 116 | 117 | @external("env", "BeginDrawing") 118 | export declare function BeginDrawing() :void 119 | 120 | @external("env", "EndDrawing") 121 | export declare function EndDrawing() :void 122 | 123 | // these need to be wrapped to convert strings & Colors 124 | 125 | @external("env", "TraceLog") 126 | declare function _TraceLog(logLevel: i32, text: ArrayBuffer) :void 127 | export function TraceLog(logLevel: i32, text: string) :void { 128 | _TraceLog(logLevel, String.UTF8.encode(text, true)) 129 | } 130 | 131 | @external("env", "InitWindow") 132 | declare function _InitWindow(width: i32, height: i32, text: ArrayBuffer) :void 133 | export function InitWindow(width: i32, height:i32, title: string) :void { 134 | _InitWindow(width, height, String.UTF8.encode(title, true)) 135 | } 136 | 137 | // these have colors spread, but this isn't really needed (since color struct fits inside an int32) 138 | // here is an example util: 139 | 140 | // convert a Color to an i32 (to pass over wasm) 141 | function toColor(color: Color): i32 { 142 | return ((color.r & 0xFF) << 24) + ((color.g & 0xFF) << 16) + ((color.b) << 8) + (color.a & 0xFF) 143 | } 144 | 145 | @external("env", "ClearBackgroundExpanded") 146 | declare function ClearBackgroundExpanded(r: i32, g: i32, b: i32, a: i32) :void 147 | export function ClearBackground(color: Color): void { 148 | ClearBackgroundExpanded(color.r, color.g, color.b, color.a) 149 | } 150 | 151 | @external("env", "DrawTextExpanded") 152 | declare function DrawTextExpanded(text: ArrayBuffer, x: i32, y: i32, fontSize: i32, r: i32, g: i32, b: i32, a: i32) :void 153 | export function DrawText(text: string, x: i32, y: i32, fontSize: i32, color: Color) :void { 154 | DrawTextExpanded(String.UTF8.encode(text, true), x, y, fontSize, color.r, color.g, color.b, color.a) 155 | } 156 | -------------------------------------------------------------------------------- /examples/assemblyscript/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "assemblyscript/std/assembly.json", 3 | "include": [ 4 | "./src/**/*.ts" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /examples/c/Makefile: -------------------------------------------------------------------------------- 1 | ifndef WASI_SDK_PATH 2 | $(error Download the WASI SDK (https://github.com/WebAssembly/wasi-sdk) and set $$WASI_SDK_PATH) 3 | endif 4 | 5 | CC = $(WASI_SDK_PATH)/bin/clang --sysroot="$(WASI_SDK_PATH)/share/wasi-sysroot" 6 | CXX = $(WASI_SDK_PATH)/bin/clang++ --sysroot="$(WASI_SDK_PATH)/share/wasi-sysroot" 7 | 8 | # Optional dependency from binaryen for smaller builds 9 | WASM_OPT = wasm-opt 10 | WASM_OPT_FLAGS = -Oz --zero-filled-memory --strip-producers 11 | 12 | # Whether to build for debugging instead of release 13 | DEBUG = 0 14 | 15 | # Compilation flags 16 | CFLAGS = -W -Wall -Wextra -Werror -Wno-unused -MMD -MP -fno-exceptions 17 | ifeq ($(DEBUG), 1) 18 | CFLAGS += -DDEBUG -O0 -g 19 | else 20 | CFLAGS += -DNDEBUG -Oz -flto 21 | endif 22 | 23 | # Linker flags 24 | LDFLAGS = -Wl,-zstack-size=1024,--no-entry,--import-memory -mexec-model=reactor \ 25 | -Wl,--initial-memory=65536,--max-memory=65536,--global-base=6560 26 | ifeq ($(DEBUG), 1) 27 | LDFLAGS += -Wl,--export-all,--no-gc-sections 28 | else 29 | LDFLAGS += -Wl,--strip-all,--gc-sections,--lto-O3 -Oz 30 | endif 31 | 32 | OBJECTS = $(patsubst src/%.c, build/%.o, $(wildcard src/*.c)) 33 | OBJECTS += $(patsubst src/%.cpp, build/%.o, $(wildcard src/*.cpp)) 34 | DEPS = $(OBJECTS:.o=.d) 35 | 36 | ifeq ($(OS), Windows_NT) 37 | MKDIR = md 38 | RMDIR = rd /s /q 39 | else 40 | MKDIR = mkdir -p 41 | RMDIR = rm -rf 42 | endif 43 | 44 | all: build/cart.wasm 45 | 46 | # Link cart.wasm from all object files and run wasm-opt 47 | build/cart.wasm: $(OBJECTS) 48 | $(CXX) -o $@ $(OBJECTS) $(LDFLAGS) 49 | ifneq ($(DEBUG), 1) 50 | ifeq (, $(shell which $(WASM_OPT))) 51 | @echo Tip: $(WASM_OPT) was not found. Install it from binaryen for smaller builds! 52 | else 53 | $(WASM_OPT) $(WASM_OPT_FLAGS) $@ -o $@ 54 | endif 55 | endif 56 | 57 | # Compile C sources 58 | build/%.o: src/%.c 59 | @$(MKDIR) build 60 | $(CC) -c $< -o $@ $(CFLAGS) 61 | 62 | # Compile C++ sources 63 | build/%.o: src/%.cpp 64 | @$(MKDIR) build 65 | $(CXX) -c $< -o $@ $(CFLAGS) 66 | 67 | .PHONY: clean 68 | clean: 69 | $(RMDIR) build 70 | 71 | -include $(DEPS) 72 | -------------------------------------------------------------------------------- /examples/c/src/main.c: -------------------------------------------------------------------------------- 1 | #define RAYLIB_WASM_IMPLEMENTATION 2 | #include "raylib-wasm.h" 3 | 4 | void Init() { 5 | InitWindow(800, 450, "raylib-wasm"); 6 | SetTargetFPS(60); 7 | } 8 | 9 | void UpdateDrawFrame() { 10 | //---------------------------------------------------------------------------------- 11 | // TODO: Update your variables here 12 | //---------------------------------------------------------------------------------- 13 | 14 | // Draw 15 | //---------------------------------------------------------------------------------- 16 | BeginDrawing(); 17 | ClearBackground(RAYWHITE); 18 | 19 | DrawText("Congrats! You created your first raylib-wasm C window!", 140, 200, 20, LIGHTGRAY); 20 | EndDrawing(); 21 | } 22 | 23 | void Close() { 24 | // Nothing. 25 | } 26 | -------------------------------------------------------------------------------- /examples/c/src/raylib-wasm.h: -------------------------------------------------------------------------------- 1 | #ifndef RAYLIB_WASM 2 | #define RAYLIB_WASM 3 | 4 | #include 5 | 6 | #define WASM_EXPORT(name) __attribute__((export_name(name))) 7 | #define WASM_IMPORT(name) __attribute__((import_name(name))) 8 | 9 | // NOTE: MSVC C++ compiler does not support compound literals (C99 feature) 10 | // Plain structures in C++ (without constructors) can be initialized with { } 11 | #if defined(__cplusplus) 12 | #define CLITERAL(type) type 13 | #else 14 | #define CLITERAL(type) (type) 15 | #endif 16 | 17 | // Some Basic Colors 18 | // NOTE: Custom raylib color palette for amazing visuals on WHITE background 19 | #define LIGHTGRAY CLITERAL(Color){ 200, 200, 200, 255 } // Light Gray 20 | #define GRAY CLITERAL(Color){ 130, 130, 130, 255 } // Gray 21 | #define DARKGRAY CLITERAL(Color){ 80, 80, 80, 255 } // Dark Gray 22 | #define YELLOW CLITERAL(Color){ 253, 249, 0, 255 } // Yellow 23 | #define GOLD CLITERAL(Color){ 255, 203, 0, 255 } // Gold 24 | #define ORANGE CLITERAL(Color){ 255, 161, 0, 255 } // Orange 25 | #define PINK CLITERAL(Color){ 255, 109, 194, 255 } // Pink 26 | #define RED CLITERAL(Color){ 230, 41, 55, 255 } // Red 27 | #define MAROON CLITERAL(Color){ 190, 33, 55, 255 } // Maroon 28 | #define GREEN CLITERAL(Color){ 0, 228, 48, 255 } // Green 29 | #define LIME CLITERAL(Color){ 0, 158, 47, 255 } // Lime 30 | #define DARKGREEN CLITERAL(Color){ 0, 117, 44, 255 } // Dark Green 31 | #define SKYBLUE CLITERAL(Color){ 102, 191, 255, 255 } // Sky Blue 32 | #define BLUE CLITERAL(Color){ 0, 121, 241, 255 } // Blue 33 | #define DARKBLUE CLITERAL(Color){ 0, 82, 172, 255 } // Dark Blue 34 | #define PURPLE CLITERAL(Color){ 200, 122, 255, 255 } // Purple 35 | #define VIOLET CLITERAL(Color){ 135, 60, 190, 255 } // Violet 36 | #define DARKPURPLE CLITERAL(Color){ 112, 31, 126, 255 } // Dark Purple 37 | #define BEIGE CLITERAL(Color){ 211, 176, 131, 255 } // Beige 38 | #define BROWN CLITERAL(Color){ 127, 106, 79, 255 } // Brown 39 | #define DARKBROWN CLITERAL(Color){ 76, 63, 47, 255 } // Dark Brown 40 | 41 | #define WHITE CLITERAL(Color){ 255, 255, 255, 255 } // White 42 | #define BLACK CLITERAL(Color){ 0, 0, 0, 255 } // Black 43 | #define BLANK CLITERAL(Color){ 0, 0, 0, 0 } // Blank (Transparent) 44 | #define MAGENTA CLITERAL(Color){ 255, 0, 255, 255 } // Magenta 45 | #define RAYWHITE CLITERAL(Color){ 245, 245, 245, 255 } // My own White (raylib logo) 46 | 47 | // Trace log level 48 | // NOTE: Organized by priority level 49 | typedef enum { 50 | LOG_ALL = 0, // Display all logs 51 | LOG_TRACE, // Trace logging, intended for internal use only 52 | LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds 53 | LOG_INFO, // Info logging, used for program execution info 54 | LOG_WARNING, // Warning logging, used on recoverable failures 55 | LOG_ERROR, // Error logging, used on unrecoverable failures 56 | LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) 57 | LOG_NONE // Disable logging 58 | } TraceLogLevel; 59 | 60 | // Color, 4 components, R8G8B8A8 (32bit) 61 | typedef struct Color { 62 | unsigned char r; // Color red value 63 | unsigned char g; // Color green value 64 | unsigned char b; // Color blue value 65 | unsigned char a; // Color alpha value 66 | } Color; 67 | 68 | WASM_EXPORT("Init") 69 | void Init(); 70 | 71 | WASM_EXPORT("UpdateDrawFrame") 72 | void UpdateDrawFrame(); 73 | 74 | WASM_EXPORT("Close") 75 | void Close(); 76 | 77 | WASM_IMPORT("InitWindow") 78 | void InitWindow(int width, int height, const char *title); 79 | 80 | WASM_IMPORT("BeginDrawing") 81 | void BeginDrawing(); 82 | 83 | WASM_IMPORT("ClearBackgroundExpanded") 84 | void ClearBackgroundExpanded(int r, int g, int b, int a); 85 | 86 | WASM_IMPORT("DrawTextExpanded") 87 | void DrawTextExpanded(const char *text, int posX, int posY, int fontSize, int r, int g, int b, int a); 88 | 89 | WASM_IMPORT("ClearBackground") 90 | void ClearBackground(Color color); 91 | 92 | WASM_IMPORT("SetTargetFPS") 93 | void SetTargetFPS(int fps); 94 | 95 | WASM_IMPORT("EndDrawing") 96 | void EndDrawing(); 97 | 98 | WASM_IMPORT("CloseWindow") 99 | void CloseWindow(); 100 | 101 | WASM_IMPORT("TraceLog") 102 | void TraceLog(int logLevel, const char* text); 103 | 104 | // Function wrappers 105 | //void ClearBackground(Color color); 106 | void DrawText(const char* text, int posX, int posY, int fontSize, Color color); 107 | 108 | #ifdef RAYLIB_WASM_IMPLEMENTATION 109 | #ifndef RAYLIB_WASM_IMPLEMENTATION_ONCE 110 | #define RAYLIB_WASM_IMPLEMENTATION_ONCE 111 | 112 | inline void ClearBackground(Color color) { 113 | ClearBackgroundExpanded(color.r, color.g, color.b, color.a); 114 | } 115 | 116 | inline void DrawText(const char* text, int posX, int posY, int fontSize, Color color) { 117 | DrawTextExpanded(text, posX, posY, fontSize, color.r, color.g, color.b, color.a); 118 | } 119 | 120 | #endif // RAYLIB_WASM_IMPLEMENTATION_ONCE 121 | #endif // RAYLIB_WASM_IMPLEMENTATION 122 | 123 | #endif // RAYLIB_WASM 124 | -------------------------------------------------------------------------------- /examples/zig/.gitignore: -------------------------------------------------------------------------------- 1 | zig-cache 2 | zig-out 3 | -------------------------------------------------------------------------------- /examples/zig/README.md: -------------------------------------------------------------------------------- 1 | # Zig 2 | 3 | Zig no worky either. 4 | -------------------------------------------------------------------------------- /examples/zig/build.zig: -------------------------------------------------------------------------------- 1 | const std = @import("std"); 2 | 3 | pub fn build(b: *std.build.Builder) void { 4 | const mode = b.standardReleaseOptions(); 5 | const lib = b.addSharedLibrary("raylib-wasm-zig", "src/main.zig", .unversioned); 6 | 7 | lib.setBuildMode(mode); 8 | lib.setTarget(.{ 9 | .cpu_arch = .wasm32, 10 | .os_tag = .freestanding 11 | }); 12 | 13 | lib.import_memory = true; 14 | lib.initial_memory = 65536; 15 | lib.max_memory = 65536; 16 | lib.stack_size = 14752; 17 | 18 | //lib.setOutputDir("zig-cache"); 19 | b.default_step.dependOn(&lib.step); 20 | 21 | lib.install(); 22 | } 23 | -------------------------------------------------------------------------------- /examples/zig/src/main.zig: -------------------------------------------------------------------------------- 1 | const r = @import("raylib-wasm.zig"); 2 | 3 | 4 | export fn Init() void { 5 | //r.InitWindow(800, 450, "raylib-wasm"); 6 | //r.SetTargetFPS(60); 7 | } 8 | 9 | export fn UpdateDrawFrame() void { 10 | //---------------------------------------------------------------------------------- 11 | // TODO: Update your variables here 12 | //---------------------------------------------------------------------------------- 13 | 14 | // Draw 15 | //---------------------------------------------------------------------------------- 16 | //r.BeginDrawing(); 17 | //r.ClearBackground(r.RAYWHITE); 18 | 19 | //r.DrawText("Congrats! You created your first raylib-wasm Zig window!", 140, 200, 20, r.LIGHTGRAY); 20 | //r.EndDrawing(); 21 | 22 | } 23 | 24 | export fn Close() void { 25 | //r.TraceLog(3, "ABYE!"); 26 | } 27 | 28 | // // we'll import this from JS-land 29 | // extern fn console_log_ex(message: [*]const u8, length: u8) void; 30 | 31 | // // we'll export this to JS-land 32 | // export fn add(a: i32, b: i32) i32 { 33 | // const log = "happy happy joy joy"; 34 | // console_log_ex(log, log.len); 35 | // return a + b; 36 | // } 37 | -------------------------------------------------------------------------------- /examples/zig/src/raylib-wasm.zig: -------------------------------------------------------------------------------- 1 | pub const Color = packed struct { 2 | r: u8, 3 | g: u8, 4 | b: u8, 5 | a: u8 = 255, 6 | }; 7 | 8 | 9 | // Some Basic Colors 10 | // NOTE: Custom raylib color palette for amazing visuals on WHITE background 11 | pub const LIGHTGRAY = Color{.r=200, .g=200, .b=200 }; // Light Gray 12 | pub const GRAY = Color{.r=130, .g=130, .b=130 }; // Gray 13 | pub const DARKGRAY = Color{.r=80, .g=80, .b=80 }; // Dark Gray 14 | pub const YELLOW = Color{.r=253, .g=249, .b=0 }; // Yellow 15 | pub const GOLD = Color{.r=255, .g=203, .b=0 }; // Gold 16 | pub const ORANGE = Color{.r=255, .g=161, .b=0 }; // Orange 17 | pub const PINK = Color{.r=255, .g=109, .b=194 }; // Pink 18 | pub const RED = Color{.r=230, .g=41, .b=55 }; // Red 19 | pub const MAROON = Color{.r=190, .g=33, .b=55 }; // Maroon 20 | pub const GREEN = Color{.r=0, .g=228, .b=48 }; // Green 21 | pub const LIME = Color{.r=0, .g=158, .b=47 }; // Lime 22 | pub const DARKGREEN = Color{.r=0, .g=117, .b=44 }; // Dark Green 23 | pub const SKYBLUE = Color{.r=102, .g=191, .b=255 }; // Sky Blue 24 | pub const BLUE = Color{.r=0, .g=121, .b=241 }; // Blue 25 | pub const DARKBLUE = Color{.r=0, .g=82, .b=172 }; // Dark Blue 26 | pub const PURPLE = Color{.r=200, .g=122, .b=255 }; // Purple 27 | pub const VIOLET = Color{.r=135, .g=60, .b=190 }; // Violet 28 | pub const DARKPURPLE= Color{.r=112, .g=31, .b=126 }; // Dark Purple 29 | pub const BEIGE = Color{.r=211, .g=176, .b=131 }; // Beige 30 | pub const BROWN = Color{.r=127, .g=106, .b=79 }; // Brown 31 | pub const DARKBROWN = Color{.r=76, .g=63, .b=47 }; // Dark Brown 32 | pub const WHITE = Color{.r=255, .g=255, .b=255 }; // White 33 | pub const BLACK = Color{.r=0, .g=0, .b=0 }; // Black 34 | pub const BLANK = Color{.r=0, .g=0, .b=0, .a=0 }; // Blank (Transparent) 35 | pub const MAGENTA = Color{.r=255, .g=0, .b=255 }; // Magenta 36 | pub const RAYWHITE = Color{.r=245, .g=245, .b=245 }; // My own White (raylib logo) 37 | 38 | 39 | // Trace log level 40 | // NOTE: Organized by priority level 41 | // pub enum TraceLogLevel { 42 | // LOG_ALL = 0, // Display all logs 43 | // LOG_TRACE, // Trace logging, intended for internal use only 44 | // LOG_DEBUG, // Debug logging, used for internal debugging, it should be disabled on release builds 45 | // LOG_INFO, // Info logging, used for program execution info 46 | // LOG_WARNING, // Warning logging, used on recoverable failures 47 | // LOG_ERROR, // Error logging, used on unrecoverable failures 48 | // LOG_FATAL, // Fatal logging, used to abort program: exit(EXIT_FAILURE) 49 | // LOG_NONE, // Disable logging 50 | // }; 51 | 52 | 53 | //pub extern fn InitWindow(width: i32, height: i32, title:[*]const u8) void; 54 | 55 | pub extern fn BeginDrawing() void; 56 | 57 | pub extern fn ClearBackgroundExpanded(r: i32, g: i32, b: i32, a: i32) void; 58 | 59 | //pub extern fn DrawTextExpanded(text:[]const u8, posX: i32, posY: i32, fontSize: i32, r: i32, g: i32, b: i32, a: i32) void; 60 | 61 | pub extern fn SetTargetFPS(fps:i32) void; 62 | 63 | pub extern fn EndDrawing() void; 64 | 65 | pub extern fn CloseWindow() void; 66 | 67 | //pub extern fn TraceLog(logLevel:i32, text:[*]const u8) void; 68 | 69 | pub fn ClearBackground(color:Color) void { 70 | ClearBackgroundExpanded(color.r, color.g, color.b, color.a); 71 | } 72 | 73 | // pub fn DrawText(text:[]const u8, posX:i32, posY:i32, fontSize:i32, color:Color) void { 74 | // //DrawTextExpanded(text, posX, posY, fontSize, color.r, color.g, color.b, color.a); 75 | // } 76 | -------------------------------------------------------------------------------- /examples/zig/www/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | WASM Test 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /examples/zig/www/wasmtest.js: -------------------------------------------------------------------------------- 1 | // just keep a global ref to the instance around for convenience 2 | var instance; 3 | // this function will be imported for wasm to use 4 | function console_log_ex(location, size) { 5 | var buffer = new Uint8Array(instance.exports.memory.buffer, location, size); 6 | var decoder = new TextDecoder(); 7 | var string = decoder.decode(buffer); 8 | console.log(string); 9 | } 10 | // define our imports 11 | var imports = { 12 | env: { 13 | console_log_ex: console_log_ex 14 | } 15 | }; 16 | // do the thing 17 | fetch("wasmtest.wasm") 18 | .then(function (response) { return response.arrayBuffer(); }) 19 | .then(function (bytes) { return WebAssembly.instantiate(bytes, imports); }) 20 | .then(function (results) { 21 | instance = results.instance; 22 | // grab our exported function from wasm 23 | var add = results.instance.exports.add; 24 | console.log(add(3, 4)); 25 | }); 26 | -------------------------------------------------------------------------------- /runtimes/wasi/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.11) 2 | project(raylib-wasm 3 | DESCRIPTION "raylib-wasm: WebAssembly for raylib" 4 | HOMEPAGE_URL "https://github.com/robloach/raylib-wasm" 5 | VERSION 4.5.0 6 | LANGUAGES C 7 | ) 8 | 9 | # raylib 10 | find_package(raylib QUIET) 11 | if (NOT raylib_FOUND) 12 | include(FetchContent) 13 | FetchContent_Declare( 14 | raylib 15 | GIT_REPOSITORY https://github.com/raysan5/raylib.git 16 | GIT_TAG 4.5.0 17 | ) 18 | FetchContent_GetProperties(raylib) 19 | if (NOT raylib_POPULATED) # Have we downloaded raylib yet? 20 | set(FETCHCONTENT_QUIET NO) 21 | FetchContent_Populate(raylib) 22 | set(BUILD_EXAMPLES OFF CACHE BOOL "" FORCE) 23 | set(BUILD_GAMES OFF CACHE BOOL "" FORCE) 24 | add_subdirectory(${raylib_SOURCE_DIR} ${raylib_BINARY_DIR}) 25 | endif() 26 | endif() 27 | 28 | # wasm3 29 | find_package(wasm3 QUIET) 30 | if (NOT wasm3_FOUND) 31 | include(FetchContent) 32 | FetchContent_Declare( 33 | wasm3 34 | GIT_REPOSITORY https://github.com/wasm3/wasm3.git 35 | GIT_TAG v0.5.0 36 | ) 37 | FetchContent_GetProperties(wasm3) 38 | if (NOT wasm3_POPULATED) # Have we downloaded raylib yet? 39 | set(FETCHCONTENT_QUIET NO) 40 | FetchContent_Populate(wasm3) 41 | add_subdirectory(${wasm3_SOURCE_DIR} ${wasm3_BINARY_DIR}) 42 | endif() 43 | endif() 44 | 45 | # raylib-wasm 46 | add_executable(raylib-wasm 47 | main.c 48 | ) 49 | 50 | target_link_libraries(raylib-wasm PUBLIC 51 | raylib 52 | m3 53 | ) 54 | -------------------------------------------------------------------------------- /runtimes/wasi/main.c: -------------------------------------------------------------------------------- 1 | #include "raylib.h" 2 | #include "wasm3.h" 3 | #include "m3_env.h" 4 | 5 | #define RUNTIME_SIZE 1024 6 | 7 | static m3ApiRawFunction (InitWindowBinding) { 8 | m3ApiGetArg(int, width); 9 | m3ApiGetArg(int, height); 10 | m3ApiGetArgMem(const char *, title); 11 | InitWindow(width, height, title); 12 | m3ApiSuccess(); 13 | } 14 | 15 | static m3ApiRawFunction (BeginDrawingBinding) { 16 | BeginDrawing(); 17 | m3ApiSuccess(); 18 | } 19 | 20 | static m3ApiRawFunction (ClearBackgroundExpandedBinding) { 21 | m3ApiGetArg(int, colorR); 22 | m3ApiGetArg(int, colorG); 23 | m3ApiGetArg(int, colorB); 24 | m3ApiGetArg(int, colorA); 25 | Color color; 26 | color.r = colorR; 27 | color.g = colorG; 28 | color.b = colorB; 29 | color.a = colorA; 30 | ClearBackground(color); 31 | m3ApiSuccess(); 32 | } 33 | 34 | static m3ApiRawFunction (DrawTextExpandedBinding) { 35 | m3ApiGetArgMem(const char *, text); 36 | m3ApiGetArg(int, posX); 37 | m3ApiGetArg(int, posY); 38 | m3ApiGetArg(int, fontSize); 39 | m3ApiGetArg(int, colorR); 40 | m3ApiGetArg(int, colorG); 41 | m3ApiGetArg(int, colorB); 42 | m3ApiGetArg(int, colorA); 43 | Color color; 44 | color.r = colorR; 45 | color.g = colorG; 46 | color.b = colorB; 47 | color.a = colorA; 48 | DrawText(text, posX, posY, fontSize, color); 49 | m3ApiSuccess(); 50 | } 51 | 52 | static m3ApiRawFunction (GetFPSBinding) { 53 | m3ApiReturnType(int); 54 | int fps = GetFPS(); 55 | m3ApiReturn(fps); 56 | } 57 | 58 | static m3ApiRawFunction (TraceLogBinding) { 59 | m3ApiGetArg(int, logLevel); 60 | m3ApiGetArgMem(const char *, text); 61 | TraceLog(logLevel, text); 62 | m3ApiSuccess(); 63 | } 64 | 65 | static m3ApiRawFunction (SetTargetFPSBinding) { 66 | m3ApiGetArg(int, fps); 67 | SetTargetFPS(fps); 68 | m3ApiSuccess(); 69 | } 70 | 71 | static m3ApiRawFunction (EndDrawingBinding) { 72 | EndDrawing(); 73 | m3ApiSuccess(); 74 | } 75 | 76 | static m3ApiRawFunction (CloseWindowBinding) { 77 | CloseWindow(); 78 | m3ApiSuccess(); 79 | } 80 | 81 | // all wasm3 functions return same sort of error-pattern, so this wraps that 82 | static void CheckWasm3Error(M3Runtime* runtime, M3Result result) { 83 | if (result) { 84 | M3ErrorInfo info; 85 | m3_GetErrorInfo(runtime, &info); 86 | TraceLog(LOG_ERROR, "%s - %s", result, info.message); 87 | } 88 | } 89 | 90 | 91 | int main(int argc, char *argv[]) { 92 | if (argc < 2) { 93 | TraceLog(LOG_ERROR, "Need an arg"); 94 | return 1; 95 | } 96 | 97 | // Make sure the file exists. 98 | const char* filename = argv[1]; 99 | if (!FileExists(filename)) { 100 | TraceLog(LOG_ERROR, "File not found: %s", filename); 101 | return 1; 102 | } 103 | 104 | unsigned int bytesRead; 105 | unsigned char* fileData = LoadFileData(filename, &bytesRead); 106 | if (bytesRead == 0) { 107 | TraceLog(LOG_FATAL, "Could not load file"); 108 | return 1; 109 | } 110 | 111 | M3Result result = m3Err_none; 112 | 113 | IM3Environment env = m3_NewEnvironment(); 114 | if (!env) { 115 | TraceLog(LOG_FATAL, "m3_NewEnvironment failed"); 116 | UnloadFileData(fileData); 117 | return 1; 118 | } 119 | 120 | IM3Runtime runtime = m3_NewRuntime(env, RUNTIME_SIZE, NULL); 121 | if (!runtime) { 122 | TraceLog(LOG_FATAL, "m3_NewRuntime failed"); 123 | UnloadFileData(fileData); 124 | return 1; 125 | } 126 | 127 | //TraceLog(LOG_INFO, "ResizeMemory"); 128 | runtime->memory.maxPages = 1024; 129 | ResizeMemory(runtime, 1024); 130 | 131 | IM3Module module; 132 | result = m3_ParseModule(env, &module, fileData, bytesRead); 133 | UnloadFileData(fileData); 134 | if (result) { 135 | TraceLog(LOG_FATAL, "m3_ParseModule: %s", result); 136 | return 1; 137 | } 138 | 139 | module->memoryImported = true; 140 | result = m3_LoadModule(runtime, module); 141 | if (result) { 142 | TraceLog(LOG_FATAL, "m3_LoadModule: %s", result); 143 | return 1; 144 | } 145 | 146 | // Imports 147 | m3_LinkRawFunction(module, "env", "InitWindow", "v(iii)", &InitWindowBinding); 148 | m3_LinkRawFunction(module, "env", "TraceLog", "v(ii)", &TraceLogBinding); 149 | m3_LinkRawFunction(module, "env", "CloseWindow", "v()", &CloseWindowBinding); 150 | m3_LinkRawFunction(module, "env", "BeginDrawing", "v()", &BeginDrawingBinding); 151 | m3_LinkRawFunction(module, "env", "ClearBackgroundExpanded", "v(iiii)", ClearBackgroundExpandedBinding); 152 | m3_LinkRawFunction(module, "env", "DrawTextExpanded", "v(iiiiiiii)", DrawTextExpandedBinding); 153 | m3_LinkRawFunction(module, "env", "SetTargetFPS", "v(i)", &SetTargetFPSBinding); 154 | m3_LinkRawFunction(module, "env", "EndDrawing", "v()", &EndDrawingBinding); 155 | m3_LinkRawFunction(module, "env", "GetFPS", "i()", &GetFPSBinding); 156 | 157 | M3ErrorInfo error; 158 | m3_GetErrorInfo(runtime, &error); 159 | if (error.result) { 160 | TraceLog(LOG_ERROR, "%s - %s", error.result, error.message); 161 | return 1; 162 | } 163 | 164 | M3Function* init; 165 | M3Function* updateDrawFrame; 166 | M3Function* close; 167 | m3_FindFunction(&init, runtime, "Init"); 168 | m3_FindFunction(&updateDrawFrame, runtime, "UpdateDrawFrame"); 169 | m3_FindFunction(&close, runtime, "Close"); 170 | 171 | if (init) { 172 | result = m3_Call(init, 0, NULL); 173 | if (result) { 174 | CheckWasm3Error(runtime, result); 175 | } 176 | } 177 | else { 178 | TraceLog(LOG_WARNING, "No Init() function"); 179 | } 180 | 181 | while (!WindowShouldClose()) { 182 | if (updateDrawFrame) { 183 | result = m3_Call(updateDrawFrame, 0, NULL); 184 | if (result) { 185 | CheckWasm3Error(runtime, result); 186 | } 187 | } 188 | } 189 | 190 | if (close) { 191 | result = m3_Call(close, 0, NULL); 192 | if (result) { 193 | CheckWasm3Error(runtime, result); 194 | } 195 | } 196 | else { 197 | TraceLog(LOG_WARNING, "No Close() function"); 198 | } 199 | 200 | // Force it to close if it didn't. 201 | if (IsWindowReady()) { 202 | CloseWindow(); 203 | } 204 | 205 | return 0; 206 | } 207 | --------------------------------------------------------------------------------