@dayme/bunraylib 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,92 @@
1
+ import { FFIType } from "bun:ffi";
2
+ const { i32, ptr } = FFIType;
3
+
4
+ export const shapesSymbols = {
5
+ DrawRectangleW: { args: [i32, i32, i32, i32, i32], returns: FFIType.void },
6
+ DrawTextW: { args: [FFIType.cstring, i32, i32, i32, i32], returns: FFIType.void },
7
+ DrawPixelW: { args: [i32, i32, i32], returns: FFIType.void },
8
+ DrawLineW: { args: [i32, i32, i32, i32, i32], returns: FFIType.void },
9
+ DrawLineExW: { args: [i32, i32, i32, i32, i32, i32], returns: FFIType.void },
10
+ DrawLineStripW: { args: [ptr, i32, i32], returns: FFIType.void },
11
+ DrawLineBezierW: { args: [i32, i32, i32, i32, i32, i32], returns: FFIType.void },
12
+ DrawCircleW: { args: [i32, i32, i32, i32], returns: FFIType.void },
13
+ DrawCircleSectorW: { args: [i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
14
+ DrawCircleSectorLinesW: { args: [i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
15
+ DrawCircleGradientW: { args: [i32, i32, i32, i32, i32], returns: FFIType.void },
16
+ DrawCircleLinesW: { args: [i32, i32, i32, i32], returns: FFIType.void },
17
+ DrawEllipseW: { args: [i32, i32, i32, i32, i32], returns: FFIType.void },
18
+ DrawEllipseLinesW: { args: [i32, i32, i32, i32, i32], returns: FFIType.void },
19
+ DrawRingW: { args: [i32, i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
20
+ DrawRingLinesW: { args: [i32, i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
21
+ DrawRectangleProW: { args: [i32, i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
22
+ DrawRectangleGradientVW: { args: [i32, i32, i32, i32, i32, i32], returns: FFIType.void },
23
+ DrawRectangleGradientHW: { args: [i32, i32, i32, i32, i32, i32], returns: FFIType.void },
24
+ DrawRectangleGradientExW: {
25
+ args: [i32, i32, i32, i32, i32, i32, i32, i32],
26
+ returns: FFIType.void,
27
+ },
28
+ DrawRectangleLinesW: { args: [i32, i32, i32, i32, i32], returns: FFIType.void },
29
+ DrawRectangleLinesExW: { args: [i32, i32, i32, i32, i32, i32], returns: FFIType.void },
30
+ DrawRectangleRoundedW: { args: [i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
31
+ DrawRectangleRoundedLinesW: { args: [i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
32
+ DrawRectangleRoundedLinesExW: {
33
+ args: [i32, i32, i32, i32, i32, i32, i32, i32],
34
+ returns: FFIType.void,
35
+ },
36
+ DrawTriangleW: { args: [i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
37
+ DrawTriangleLinesW: { args: [i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
38
+ DrawTriangleFanW: { args: [ptr, i32, i32], returns: FFIType.void },
39
+ DrawTriangleStripW: { args: [ptr, i32, i32], returns: FFIType.void },
40
+ DrawPolyW: { args: [i32, i32, i32, i32, i32, i32], returns: FFIType.void },
41
+ DrawPolyLinesW: { args: [i32, i32, i32, i32, i32, i32], returns: FFIType.void },
42
+ DrawPolyLinesExW: { args: [i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
43
+ DrawSplineLinearW: { args: [ptr, i32, i32, i32], returns: FFIType.void },
44
+ DrawSplineBasisW: { args: [ptr, i32, i32, i32], returns: FFIType.void },
45
+ DrawSplineCatmullRomW: { args: [ptr, i32, i32, i32], returns: FFIType.void },
46
+ DrawSplineBezierQuadraticW: { args: [ptr, i32, i32, i32], returns: FFIType.void },
47
+ DrawSplineBezierCubicW: { args: [ptr, i32, i32, i32], returns: FFIType.void },
48
+ DrawSplineSegmentLinearW: { args: [i32, i32, i32, i32, i32, i32], returns: FFIType.void },
49
+ DrawSplineSegmentBasisW: {
50
+ args: [i32, i32, i32, i32, i32, i32, i32, i32, i32, i32],
51
+ returns: FFIType.void,
52
+ },
53
+ DrawSplineSegmentCatmullRomW: {
54
+ args: [i32, i32, i32, i32, i32, i32, i32, i32, i32, i32],
55
+ returns: FFIType.void,
56
+ },
57
+ DrawSplineSegmentBezierQuadraticW: {
58
+ args: [i32, i32, i32, i32, i32, i32, i32, i32],
59
+ returns: FFIType.void,
60
+ },
61
+ DrawSplineSegmentBezierCubicW: {
62
+ args: [i32, i32, i32, i32, i32, i32, i32, i32, i32, i32],
63
+ returns: FFIType.void,
64
+ },
65
+ GetSplinePointLinearW: { args: [ptr, i32, i32, i32, i32, i32], returns: FFIType.void },
66
+ GetSplinePointBasisW: {
67
+ args: [ptr, i32, i32, i32, i32, i32, i32, i32, i32, i32],
68
+ returns: FFIType.void,
69
+ },
70
+ GetSplinePointCatmullRomW: {
71
+ args: [ptr, i32, i32, i32, i32, i32, i32, i32, i32, i32],
72
+ returns: FFIType.void,
73
+ },
74
+ GetSplinePointBezierQuadW: {
75
+ args: [ptr, i32, i32, i32, i32, i32, i32, i32],
76
+ returns: FFIType.void,
77
+ },
78
+ GetSplinePointBezierCubicW: {
79
+ args: [ptr, i32, i32, i32, i32, i32, i32, i32, i32, i32],
80
+ returns: FFIType.void,
81
+ },
82
+ DrawPixelVW: { args: [i32, i32, i32], returns: FFIType.void },
83
+ DrawLineVW: { args: [i32, i32, i32, i32, i32], returns: FFIType.void },
84
+ DrawCircleVW: { args: [i32, i32, i32, i32], returns: FFIType.void },
85
+ DrawCircleLinesVW: { args: [i32, i32, i32, i32], returns: FFIType.void },
86
+ DrawRectangleVW: { args: [i32, i32, i32, i32, i32], returns: FFIType.void },
87
+ DrawRectangleRecW: { args: [i32, i32, i32, i32, i32], returns: FFIType.void },
88
+ SetShapesTextureW: { args: [i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
89
+ GetShapesTextureW: { args: [ptr, ptr, ptr], returns: FFIType.void },
90
+ GetShapesTextureRectangleW: { args: [ptr], returns: FFIType.void },
91
+ DrawFPSW: { args: [i32, i32], returns: FFIType.void },
92
+ } as const;
@@ -0,0 +1,56 @@
1
+ import { FFIType } from "bun:ffi";
2
+ const { i32, ptr, bool } = FFIType;
3
+
4
+ export const textureSymbols = {
5
+ LoadTextureW: { args: [ptr, ptr, ptr, FFIType.cstring], returns: FFIType.void },
6
+ UnloadTextureW: { args: [i32], returns: FFIType.void },
7
+ IsTextureValidW: { args: [i32, i32, i32], returns: bool },
8
+ LoadRenderTextureW: { args: [ptr, ptr, ptr, ptr, i32, i32], returns: FFIType.void },
9
+ UnloadRenderTextureW: { args: [i32], returns: FFIType.void },
10
+ IsRenderTextureValidW: { args: [i32], returns: bool },
11
+ GenTextureMipmapsW: { args: [i32], returns: FFIType.void },
12
+ SetTextureFilterW: { args: [i32, i32], returns: FFIType.void },
13
+ SetTextureWrapW: { args: [i32, i32], returns: FFIType.void },
14
+ DrawTextureW: { args: [i32, i32, i32, i32, i32, i32], returns: FFIType.void },
15
+ DrawTextureVW: { args: [i32, i32, i32, i32, i32, i32], returns: FFIType.void },
16
+ DrawTextureExW: { args: [i32, i32, i32, i32, i32, i32, i32, i32], returns: FFIType.void },
17
+ DrawTextureRecW: {
18
+ args: [i32, i32, i32, i32, i32, i32, i32, i32, i32, i32],
19
+ returns: FFIType.void,
20
+ },
21
+ DrawTextureProW: {
22
+ args: [i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32],
23
+ returns: FFIType.void,
24
+ },
25
+ LoadTextureFromImageW: { args: [ptr, ptr, ptr, i32], returns: FFIType.void },
26
+ LoadTextureCubemapW: { args: [ptr, ptr, ptr, i32, i32], returns: FFIType.void },
27
+ UpdateTextureW: { args: [i32, i32, i32, ptr], returns: FFIType.void },
28
+ UpdateTextureRecW: { args: [i32, i32, i32, i32, i32, i32, i32, ptr], returns: FFIType.void },
29
+ DrawTextureNPatchW: {
30
+ args: [
31
+ i32,
32
+ i32,
33
+ i32,
34
+ i32,
35
+ i32,
36
+ i32,
37
+ i32,
38
+ i32,
39
+ i32,
40
+ i32,
41
+ i32,
42
+ i32,
43
+ i32,
44
+ i32,
45
+ i32,
46
+ i32,
47
+ i32,
48
+ i32,
49
+ i32,
50
+ i32,
51
+ ],
52
+ returns: FFIType.void,
53
+ },
54
+ GetPixelColorW: { args: [ptr, i32], returns: i32 },
55
+ SetPixelColorW: { args: [ptr, i32, i32], returns: FFIType.void },
56
+ } as const;
@@ -0,0 +1,83 @@
1
+ import { FFIType } from "bun:ffi";
2
+ const { i32, cstring, bool, f32, ptr } = FFIType;
3
+
4
+ export const windowSymbols = {
5
+ InitWindowW: { args: [i32, i32, cstring], returns: FFIType.void },
6
+ CloseWindowW: { args: [], returns: FFIType.void },
7
+ WindowShouldCloseW: { args: [], returns: bool },
8
+ BeginDrawingW: { args: [], returns: FFIType.void },
9
+ EndDrawingW: { args: [], returns: FFIType.void },
10
+ ClearBackgroundW: { args: [i32], returns: FFIType.void },
11
+ SetTargetFPSW: { args: [i32], returns: FFIType.void },
12
+ GetFrameTimeW: { args: [], returns: f32 },
13
+
14
+ IsWindowReadyW: { args: [], returns: bool },
15
+ IsWindowFullscreenW: { args: [], returns: bool },
16
+ IsWindowHiddenW: { args: [], returns: bool },
17
+ IsWindowMinimizedW: { args: [], returns: bool },
18
+ IsWindowMaximizedW: { args: [], returns: bool },
19
+ IsWindowFocusedW: { args: [], returns: bool },
20
+ IsWindowResizedW: { args: [], returns: bool },
21
+ IsWindowStateW: { args: [i32], returns: bool },
22
+ SetWindowStateW: { args: [i32], returns: FFIType.void },
23
+ ClearWindowStateW: { args: [i32], returns: FFIType.void },
24
+ ToggleFullscreenW: { args: [], returns: FFIType.void },
25
+ ToggleBorderlessWindowedW: { args: [], returns: FFIType.void },
26
+ MaximizeWindowW: { args: [], returns: FFIType.void },
27
+ MinimizeWindowW: { args: [], returns: FFIType.void },
28
+ RestoreWindowW: { args: [], returns: FFIType.void },
29
+ SetWindowTitleW: { args: [cstring], returns: FFIType.void },
30
+ SetWindowPositionW: { args: [i32, i32], returns: FFIType.void },
31
+ SetWindowMonitorW: { args: [i32], returns: FFIType.void },
32
+ SetWindowMinSizeW: { args: [i32, i32], returns: FFIType.void },
33
+ SetWindowMaxSizeW: { args: [i32, i32], returns: FFIType.void },
34
+ SetWindowSizeW: { args: [i32, i32], returns: FFIType.void },
35
+ SetWindowOpacityW: { args: [f32], returns: FFIType.void },
36
+ SetWindowFocusedW: { args: [], returns: FFIType.void },
37
+ GetScreenWidthW: { args: [], returns: i32 },
38
+ GetScreenHeightW: { args: [], returns: i32 },
39
+ GetRenderWidthW: { args: [], returns: i32 },
40
+ GetRenderHeightW: { args: [], returns: i32 },
41
+ GetMonitorCountW: { args: [], returns: i32 },
42
+ GetCurrentMonitorW: { args: [], returns: i32 },
43
+ GetMonitorPositionW: { args: [ptr, i32], returns: FFIType.void },
44
+ GetMonitorWidthW: { args: [i32], returns: i32 },
45
+ GetMonitorHeightW: { args: [i32], returns: i32 },
46
+ GetMonitorPhysicalWidthW: { args: [i32], returns: i32 },
47
+ GetMonitorPhysicalHeightW: { args: [i32], returns: i32 },
48
+ GetMonitorRefreshRateW: { args: [i32], returns: i32 },
49
+ GetWindowPositionW: { args: [ptr], returns: FFIType.void },
50
+ GetWindowScaleDPIW: { args: [ptr], returns: FFIType.void },
51
+ GetMonitorNameW: { args: [i32], returns: ptr },
52
+ SetClipboardTextW: { args: [cstring], returns: FFIType.void },
53
+ GetClipboardTextW: { args: [], returns: ptr },
54
+ EnableEventWaitingW: { args: [], returns: FFIType.void },
55
+ DisableEventWaitingW: { args: [], returns: FFIType.void },
56
+ ShowCursorW: { args: [], returns: FFIType.void },
57
+ HideCursorW: { args: [], returns: FFIType.void },
58
+ IsCursorHiddenW: { args: [], returns: bool },
59
+ EnableCursorW: { args: [], returns: FFIType.void },
60
+ DisableCursorW: { args: [], returns: FFIType.void },
61
+ IsCursorOnScreenW: { args: [], returns: bool },
62
+ BeginTextureModeW: { args: [i32, i32, i32], returns: FFIType.void },
63
+ EndTextureModeW: { args: [], returns: FFIType.void },
64
+ BeginBlendModeW: { args: [i32], returns: FFIType.void },
65
+ EndBlendModeW: { args: [], returns: FFIType.void },
66
+ BeginScissorModeW: { args: [i32, i32, i32, i32], returns: FFIType.void },
67
+ EndScissorModeW: { args: [], returns: FFIType.void },
68
+ GetTimeW: { args: [], returns: FFIType.f64 },
69
+ GetFPSW: { args: [], returns: i32 },
70
+ SwapScreenBufferW: { args: [], returns: FFIType.void },
71
+ PollInputEventsW: { args: [], returns: FFIType.void },
72
+ WaitTimeW: { args: [FFIType.f64], returns: FFIType.void },
73
+ SetRandomSeedW: { args: [i32], returns: FFIType.void },
74
+ GetRandomValueW: { args: [i32, i32], returns: i32 },
75
+ TakeScreenshotW: { args: [cstring], returns: FFIType.void },
76
+ SetConfigFlagsW: { args: [i32], returns: FFIType.void },
77
+ OpenURLW: { args: [cstring], returns: FFIType.void },
78
+ TraceLogW: { args: [i32, cstring], returns: FFIType.void },
79
+ SetTraceLogLevelW: { args: [i32], returns: FFIType.void },
80
+ SetWindowIconW: { args: [i32], returns: FFIType.void },
81
+ GetClipboardImageW: { args: [], returns: i32 },
82
+ SetWindowIconsW: { args: [ptr, i32], returns: FFIType.void },
83
+ } as const;
package/src/symbols.ts ADDED
@@ -0,0 +1,131 @@
1
+ import { cc } from "bun:ffi";
2
+ import { writeFileSync, mkdirSync, existsSync } from "fs";
3
+ import { join, dirname } from "path";
4
+ import { tmpdir } from "os";
5
+
6
+ import { windowSymbols } from "./symbols/window";
7
+ import { shapesSymbols } from "./symbols/shapes";
8
+ import { collisionSymbols } from "./symbols/collision";
9
+ import { cameraSymbols } from "./symbols/camera";
10
+ import { draw3dSymbols } from "./symbols/draw3d";
11
+ import { textureSymbols } from "./symbols/texture";
12
+ import { modelSymbols } from "./symbols/model";
13
+ import { imageSymbols } from "./symbols/image";
14
+ import { colorSymbols } from "./symbols/color";
15
+ import { fontSymbols } from "./symbols/font";
16
+ import { inputSymbols } from "./symbols/input";
17
+ import { audioSymbols } from "./symbols/audio";
18
+ import { shaderSymbols } from "./symbols/shader";
19
+ import { filesystemSymbols } from "./symbols/filesystem";
20
+
21
+ const allSymbols = {
22
+ ...windowSymbols,
23
+ ...shapesSymbols,
24
+ ...collisionSymbols,
25
+ ...cameraSymbols,
26
+ ...draw3dSymbols,
27
+ ...textureSymbols,
28
+ ...modelSymbols,
29
+ ...imageSymbols,
30
+ ...colorSymbols,
31
+ ...fontSymbols,
32
+ ...inputSymbols,
33
+ ...audioSymbols,
34
+ ...shaderSymbols,
35
+ ...filesystemSymbols,
36
+ };
37
+
38
+ type SymbolsType = ReturnType<typeof cc<typeof allSymbols>>;
39
+
40
+ export interface RaylibConfig {
41
+ maxModels?: number;
42
+ maxFonts?: number;
43
+ maxImages?: number;
44
+ maxMeshes?: number;
45
+ maxMaterials?: number;
46
+ maxAnimations?: number;
47
+ maxShaders?: number;
48
+ maxWaves?: number;
49
+ maxSounds?: number;
50
+ maxMusic?: number;
51
+ maxAudioStreams?: number;
52
+ raylibPath?: string;
53
+ }
54
+
55
+ const defaults: Required<Omit<RaylibConfig, "raylibPath">> = {
56
+ maxModels: 64,
57
+ maxFonts: 32,
58
+ maxImages: 128,
59
+ maxMeshes: 64,
60
+ maxMaterials: 32,
61
+ maxAnimations: 32,
62
+ maxShaders: 32,
63
+ maxWaves: 32,
64
+ maxSounds: 32,
65
+ maxMusic: 16,
66
+ maxAudioStreams: 16,
67
+ };
68
+
69
+ let _config: RaylibConfig = {};
70
+ let _r: SymbolsType | null = null;
71
+
72
+ export function configure(config: RaylibConfig): void {
73
+ if (_r) throw new Error("Raylib already initialized. Call configure() before any Raylib method.");
74
+ _config = config;
75
+ }
76
+
77
+ function generateConfigHeader(config: Required<Omit<RaylibConfig, "raylibPath">>): string {
78
+ return `#ifndef CONFIG_H
79
+ #define CONFIG_H
80
+
81
+ #define MAX_MODELS ${config.maxModels}
82
+ #define MAX_FONTS ${config.maxFonts}
83
+ #define MAX_IMAGES ${config.maxImages}
84
+ #define MAX_MESHES ${config.maxMeshes}
85
+ #define MAX_MATERIALS ${config.maxMaterials}
86
+ #define MAX_ANIMATIONS ${config.maxAnimations}
87
+ #define MAX_SHADERS ${config.maxShaders}
88
+ #define MAX_WAVES ${config.maxWaves}
89
+ #define MAX_SOUNDS ${config.maxSounds}
90
+ #define MAX_MUSIC ${config.maxMusic}
91
+ #define MAX_AUDIOSTREAMS ${config.maxAudioStreams}
92
+
93
+ #endif
94
+ `;
95
+ }
96
+
97
+ function buildCC(config: RaylibConfig): SymbolsType {
98
+ const resolved = { ...defaults };
99
+ for (const key of Object.keys(defaults) as (keyof typeof defaults)[]) {
100
+ if (config[key] != null) (resolved as any)[key] = config[key];
101
+ }
102
+
103
+ const configHeader = generateConfigHeader(resolved);
104
+ const cacheDir = join(tmpdir(), "rraylib");
105
+ const configHash = Object.values(resolved).join("_");
106
+ const headerPath = join(cacheDir, `config_${configHash}.h`);
107
+
108
+ if (!existsSync(cacheDir)) mkdirSync(cacheDir, { recursive: true });
109
+ writeFileSync(headerPath, configHeader);
110
+
111
+ const srcDir = dirname(new URL(import.meta.url).pathname);
112
+ const cDir = join(srcDir, "c");
113
+
114
+ const wrapperSrc = `#include "${headerPath}"\n#include "${cDir}/registries.c"\n#include "${cDir}/window.c"\n#include "${cDir}/shapes.c"\n#include "${cDir}/collision.c"\n#include "${cDir}/camera.c"\n#include "${cDir}/draw3d.c"\n#include "${cDir}/texture.c"\n#include "${cDir}/model.c"\n#include "${cDir}/image.c"\n#include "${cDir}/color.c"\n#include "${cDir}/font.c"\n#include "${cDir}/input.c"\n#include "${cDir}/audio.c"\n#include "${cDir}/shader.c"\n#include "${cDir}/filesystem.c"\n`;
115
+
116
+ const wrapperPath = join(cacheDir, `main_${configHash}.c`);
117
+ writeFileSync(wrapperPath, wrapperSrc);
118
+
119
+ const library = config.raylibPath ? [config.raylibPath] : ["raylib"];
120
+
121
+ return cc({
122
+ source: wrapperPath,
123
+ library,
124
+ symbols: allSymbols,
125
+ });
126
+ }
127
+
128
+ export function getSymbols(): SymbolsType {
129
+ if (!_r) _r = buildCC(_config);
130
+ return _r;
131
+ }
package/src/types.ts ADDED
@@ -0,0 +1,73 @@
1
+ export type Vec2 = { x: number; y: number };
2
+ export type Vec3 = { x: number; y: number; z: number };
3
+ export type Vec4 = { x: number; y: number; z: number; w: number };
4
+ export type Rectangle = { x: number; y: number; width: number; height: number };
5
+
6
+ export type Camera2D = {
7
+ offset: Vec2;
8
+ target: Vec2;
9
+ rotation: number;
10
+ zoom: number;
11
+ };
12
+
13
+ export type CameraProjection = 0 | 1 | 2;
14
+
15
+ export type Camera3D = {
16
+ position: Vec3;
17
+ target: Vec3;
18
+ up: Vec3;
19
+ fovy: number;
20
+ projection: CameraProjection;
21
+ };
22
+
23
+ export type Ray = {
24
+ position: Vec3;
25
+ direction: Vec3;
26
+ };
27
+
28
+ export type Color = number;
29
+
30
+ export type Texture2D = {
31
+ id: number;
32
+ width: number;
33
+ height: number;
34
+ };
35
+
36
+ export type RenderTexture2D = {
37
+ id: number;
38
+ texture: Texture2D;
39
+ };
40
+
41
+ export type Model = number;
42
+
43
+ export type Font = number;
44
+
45
+ export type Image = number;
46
+ export type Shader = number;
47
+ export type Wave = number;
48
+ export type Sound = number;
49
+ export type Music = number;
50
+ export type AudioStream = number;
51
+ export type Material = number;
52
+ export type Mesh = number;
53
+ export type ModelAnimation = number;
54
+
55
+ export type BoundingBox = {
56
+ min: Vec3;
57
+ max: Vec3;
58
+ };
59
+
60
+ export type RayCollision = {
61
+ hit: boolean;
62
+ distance: number;
63
+ point: Vec3;
64
+ normal: Vec3;
65
+ };
66
+
67
+ export type GlyphInfo = {
68
+ value: number;
69
+ offsetX: number;
70
+ offsetY: number;
71
+ advanceX: number;
72
+ image: Image;
73
+ };
package/src/utils.ts ADDED
@@ -0,0 +1,25 @@
1
+ export function cstr(str: string) {
2
+ return Buffer.from(str + "\0", "utf8");
3
+ }
4
+
5
+ const _f2iBuf = new ArrayBuffer(4);
6
+ const _f2iF32 = new Float32Array(_f2iBuf);
7
+ const _f2iU32 = new Uint32Array(_f2iBuf);
8
+
9
+ export function f2i(val: number): number {
10
+ _f2iF32[0] = val;
11
+ return _f2iU32[0]! | 0;
12
+ }
13
+
14
+ const _i2fBuf = new ArrayBuffer(4);
15
+ const _i2fU32 = new Uint32Array(_i2fBuf);
16
+ const _i2fF32 = new Float32Array(_i2fBuf);
17
+
18
+ export function i2f(val: number): number {
19
+ _i2fU32[0] = val >>> 0;
20
+ return _i2fF32[0]!;
21
+ }
22
+
23
+ export const color = (r: number, g: number, b: number, a: number = 255) => {
24
+ return (a << 24) | (b << 16) | (g << 8) | r;
25
+ };