/* The C half of the raylib binding: one wrapper per `declare` in raylib.flan. * * The wrappers exist so that no aggregate is ever passed or returned across * the Flan/C boundary. raylib takes Color by value and returns Vector2 by * value, and a small aggregate is passed differently on x86-64 (<2 x float>, * i32), on arm64, and on wasm32. Here, clang classifies each one correctly for * whichever target the build is for; in the Flan backend it would be three * conventions to reimplement. Everything below therefore trades in scalars and * pointers only — see raylib.flan. * * raylib's own headers are not needed and not used: these prototypes are the * declarations, so the build has no dependency on raylib-devel being * installed, only on the shared library being linkable. */ #include #include #include #include typedef struct { float x, y; } Vector2; typedef struct { unsigned char r, g, b, a; } Color; typedef struct { unsigned int id; int width, height, mipmaps, format; } Texture2D; typedef struct { float x, y, width, height; } Rectangle; extern void InitWindow(int width, int height, const char *title); extern void CloseWindow(void); extern bool WindowShouldClose(void); extern void SetTargetFPS(int fps); extern void SetTraceLogLevel(int level); extern bool IsKeyPressed(int key); extern bool IsKeyDown(int key); extern bool IsKeyReleased(int key); extern bool IsMouseButtonPressed(int button); extern bool IsMouseButtonDown(int button); extern bool IsMouseButtonReleased(int button); extern Vector2 GetMousePosition(void); extern Color GetColor(unsigned int hex); extern void BeginDrawing(void); extern void EndDrawing(void); extern void DrawFPS(int x, int y); extern void ClearBackground(Color color); extern void DrawRectangle(int x, int y, int width, int height, Color color); extern void SetShapesTexture(Texture2D texture, Rectangle source); extern Texture2D GetShapesTexture(void); extern Rectangle GetShapesTextureRectangle(void); extern Rectangle GetCollisionRec(Rectangle a, Rectangle b); extern Texture2D LoadTexture(const char *fileName); extern bool IsTextureValid(Texture2D texture); extern void UnloadTexture(Texture2D texture); extern void DrawTexture(Texture2D texture, int posX, int posY, Color tint); extern void DrawTextureV(Texture2D texture, Vector2 position, Color tint); extern void DrawTextureEx(Texture2D texture, Vector2 position, float rotation, float scale, Color tint); extern void DrawTextureRec(Texture2D texture, Rectangle source, Vector2 position, Color tint); /* A Flan string arrives as ptr+len and is not NUL-terminated, so a C API that * wants a C string needs a copy. Two callers want one: the window title and a * texture's file path. Each passes a buffer big enough for what it is — 256 * for a title, PATH_MAX for a path — and truncating is better than reading * past the end. A truncated path fails to open and LoadTexture returns an id * of 0, which is what texture-valid? is for. */ static const char *cstr(const char *p, long long n, char *buf, size_t cap) { size_t k = (size_t)n < cap - 1 ? (size_t)n : cap - 1; memcpy(buf, p, k); buf[k] = '\0'; return buf; } void flan_rl_init_window(int width, int height, const char *title, long long n) { char buf[256]; InitWindow(width, height, cstr(title, n, buf, sizeof buf)); } void flan_rl_close_window(void) { CloseWindow(); } bool flan_rl_window_should_close(void) { return WindowShouldClose(); } void flan_rl_set_target_fps(int fps) { SetTargetFPS(fps); } void flan_rl_set_trace_log_level(int l) { SetTraceLogLevel(l); } bool flan_rl_is_key_pressed(int key) { return IsKeyPressed(key); } bool flan_rl_is_key_down(int key) { return IsKeyDown(key); } bool flan_rl_is_key_released(int key) { return IsKeyReleased(key); } bool flan_rl_is_mouse_button_pressed(int b) { return IsMouseButtonPressed(b); } bool flan_rl_is_mouse_button_down(int b) { return IsMouseButtonDown(b); } bool flan_rl_is_mouse_button_released(int b) { return IsMouseButtonReleased(b); } void flan_rl_get_mouse_position(Vector2 *out) { *out = GetMousePosition(); } void flan_rl_get_color(unsigned int hex, Color *out) { *out = GetColor(hex); } void flan_rl_begin_drawing(void) { BeginDrawing(); } void flan_rl_end_drawing(void) { EndDrawing(); } void flan_rl_draw_fps(int x, int y) { DrawFPS(x, y); } void flan_rl_clear_background(const Color *color) { ClearBackground(*color); } void flan_rl_draw_rectangle(int x, int y, int width, int height, const Color *color) { DrawRectangle(x, y, width, height, *color); } void flan_rl_set_shapes_texture(const Texture2D *texture, const Rectangle *source) { SetShapesTexture(*texture, *source); } void flan_rl_get_shapes_texture(Texture2D *out) { *out = GetShapesTexture(); } void flan_rl_get_shapes_texture_rectangle(Rectangle *out) { *out = GetShapesTextureRectangle(); } void flan_rl_get_collision_rec(const Rectangle *a, const Rectangle *b, Rectangle *out) { *out = GetCollisionRec(*a, *b); } void flan_rl_load_texture(const char *path, long long n, Texture2D *out) { char buf[PATH_MAX]; *out = LoadTexture(cstr(path, n, buf, sizeof buf)); } bool flan_rl_is_texture_valid(const Texture2D *texture) { return IsTextureValid(*texture); } void flan_rl_unload_texture(const Texture2D *texture) { UnloadTexture(*texture); } void flan_rl_draw_texture(const Texture2D *texture, int x, int y, const Color *tint) { DrawTexture(*texture, x, y, *tint); } void flan_rl_draw_texture_v(const Texture2D *texture, const Vector2 *position, const Color *tint) { DrawTextureV(*texture, *position, *tint); } void flan_rl_draw_texture_ex(const Texture2D *texture, const Vector2 *position, float rotation, float scale, const Color *tint) { DrawTextureEx(*texture, *position, rotation, scale, *tint); } void flan_rl_draw_texture_rec(const Texture2D *texture, const Rectangle *source, const Vector2 *position, const Color *tint) { DrawTextureRec(*texture, *source, *position, *tint); }