slifer 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- package/README.md +8 -6
- package/Sir-BC_stop.png +0 -0
- package/libs/libSDL2.so +0 -0
- package/libs/libSDL2_image.so +0 -0
- package/libs/libSDL2_mixer.dylib +0 -0
- package/libs/libSDL2_mixer.so +0 -0
- package/package.json +1 -1
- package/sample.wav +0 -0
- package/src/engine/renderer.ts +40 -0
- package/src/engine/time.ts +34 -0
- package/src/engine/window.ts +79 -0
- package/src/engine.ts +20 -13
- package/src/ffi.ts +257 -220
- package/src/modules/audio.ts +41 -0
- package/src/modules/graphics.ts +47 -123
- package/src/modules/keyboard.ts +80 -21
- package/src/modules/mouse.ts +22 -14
- package/src/slifer.test.ts +38 -3
- package/src/slifer.ts +32 -99
- package/bun.lockb +0 -0
package/src/modules/graphics.ts
CHANGED
@@ -1,17 +1,27 @@
|
|
1
1
|
import { libimage, libsdl, libttf } from "../ffi";
|
2
|
-
import Global from "../global";
|
3
2
|
import { type Pointer, ptr } from "bun:ffi";
|
4
3
|
import Rectangle from "../engine/rectangle";
|
5
4
|
import Color from "../color";
|
6
5
|
import Vector2 from "../engine/vector";
|
6
|
+
import Renderer from "../engine/renderer";
|
7
7
|
|
8
|
-
/** @internal */
|
9
8
|
class Graphics {
|
9
|
+
static #instance: Graphics;
|
10
|
+
|
11
|
+
static #fontPointer: Pointer;
|
12
|
+
|
13
|
+
public static get instance() {
|
14
|
+
if (!Graphics.#instance) {
|
15
|
+
Graphics.#instance = new Graphics();
|
16
|
+
}
|
17
|
+
|
18
|
+
return Graphics.#instance;
|
19
|
+
}
|
10
20
|
/**
|
11
21
|
* Slifers draw function. Used to draw everything to the screen.
|
12
22
|
*/
|
13
|
-
render() {
|
14
|
-
libsdl.symbols.SDL_RenderPresent(
|
23
|
+
public render() {
|
24
|
+
libsdl.symbols.SDL_RenderPresent(Renderer.pointer);
|
15
25
|
}
|
16
26
|
|
17
27
|
/**
|
@@ -23,7 +33,7 @@ class Graphics {
|
|
23
33
|
* @param a alpha value
|
24
34
|
* @returns Color object
|
25
35
|
*/
|
26
|
-
makeColor(r: number, g: number, b: number, a: number) {
|
36
|
+
public makeColor(r: number, g: number, b: number, a: number) {
|
27
37
|
const _color = new Color(r, g, b, a);
|
28
38
|
return _color;
|
29
39
|
}
|
@@ -36,15 +46,15 @@ class Graphics {
|
|
36
46
|
*
|
37
47
|
* @param color Color object. Make using Slifer.Graphics.makeColor
|
38
48
|
*/
|
39
|
-
setBackground(color: Color) {
|
49
|
+
public setBackground(color: Color) {
|
40
50
|
libsdl.symbols.SDL_SetRenderDrawColor(
|
41
|
-
|
51
|
+
Renderer.pointer,
|
42
52
|
color.r,
|
43
53
|
color.g,
|
44
54
|
color.b,
|
45
55
|
color.a
|
46
56
|
);
|
47
|
-
libsdl.symbols.SDL_RenderClear(
|
57
|
+
libsdl.symbols.SDL_RenderClear(Renderer.pointer);
|
48
58
|
}
|
49
59
|
|
50
60
|
/**
|
@@ -53,12 +63,12 @@ class Graphics {
|
|
53
63
|
* @param path string path to image
|
54
64
|
* @returns Image ready to draw
|
55
65
|
*/
|
56
|
-
loadImage(path: string): Image {
|
66
|
+
public loadImage(path: string): Image {
|
57
67
|
const _path = Buffer.from(path + "\x00");
|
58
68
|
const surface = libimage.symbols.IMG_Load(_path);
|
59
69
|
if (surface == null) throw `Image failed to load`;
|
60
70
|
const texture = libsdl.symbols.SDL_CreateTextureFromSurface(
|
61
|
-
|
71
|
+
Renderer.pointer,
|
62
72
|
surface
|
63
73
|
);
|
64
74
|
if (texture == null) throw `Image failed to be created`;
|
@@ -67,148 +77,63 @@ class Graphics {
|
|
67
77
|
|
68
78
|
/**
|
69
79
|
* Method to draw to the screen simply
|
80
|
+
*
|
70
81
|
* @param image Image object to draw. Made using Slifer.Graphics.loadImage
|
71
82
|
* @param position position to draw the image
|
72
83
|
*
|
73
84
|
*/
|
74
|
-
draw(image: Image, position: Vector2) {
|
85
|
+
public draw(image: Image, position: Vector2) {
|
75
86
|
const dstRect = new Uint32Array(4);
|
76
87
|
dstRect[0] = position.x;
|
77
88
|
dstRect[1] = position.y;
|
78
|
-
dstRect[2] = image.
|
79
|
-
dstRect[3] = image.
|
89
|
+
dstRect[2] = image.size.x;
|
90
|
+
dstRect[3] = image.size.y;
|
80
91
|
|
81
92
|
libsdl.symbols.SDL_RenderCopy(
|
82
|
-
|
93
|
+
Renderer.pointer,
|
83
94
|
(image as any).pointer,
|
84
95
|
null,
|
85
96
|
dstRect
|
86
97
|
);
|
87
98
|
}
|
88
99
|
|
89
|
-
|
90
|
-
* Method to draw
|
100
|
+
/*
|
101
|
+
* Method to draw to the screen with extended arguments
|
91
102
|
*
|
92
103
|
* @param image Image object to draw. Made using Slifer.Graphics.loadImage
|
93
|
-
* @param position
|
94
|
-
* @param
|
95
|
-
* @param
|
96
|
-
* @param xs (optional) scale of x axis
|
97
|
-
* @param ys (optional) scale of y axis
|
98
|
-
* @param flip (optional) horizontal flip
|
104
|
+
* @param position Position to draw the image.
|
105
|
+
* @param rotation Optional argument angle of rotation
|
106
|
+
* @param scale Optional What to multiply the width and height of image by
|
99
107
|
*/
|
100
|
-
drawEx(
|
108
|
+
public drawEx(
|
101
109
|
image: Image,
|
102
110
|
position: Vector2,
|
103
|
-
clipRectangle?: Rectangle | null,
|
104
111
|
rotation?: number,
|
105
|
-
|
106
|
-
ys?: number,
|
107
|
-
flip?: true
|
112
|
+
scale?: Vector2
|
108
113
|
) {
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
srcRect[1] = clipRectangle.position.y;
|
116
|
-
srcRect[2] = clipRectangle.size.x;
|
117
|
-
srcRect[3] = clipRectangle.size.y;
|
118
|
-
}
|
114
|
+
// Define destination rect
|
115
|
+
const dstRect = new Uint32Array(4);
|
116
|
+
dstRect[0] = position.x;
|
117
|
+
dstRect[1] = position.y;
|
118
|
+
dstRect[2] = image.size.x * (scale ? scale.x : 1);
|
119
|
+
dstRect[3] = image.size.y * (scale ? scale.y : 1);
|
119
120
|
|
120
|
-
|
121
|
-
_dest[1] = position.y;
|
122
|
-
_dest[2] = image.width * (xs ? xs : 1);
|
123
|
-
_dest[3] = image.height * (ys ? ys : 1);
|
124
|
-
const _center = new Uint32Array(2);
|
125
|
-
_center[0] = _dest[2] / 2;
|
126
|
-
_center[1] = _dest[3] / 2;
|
121
|
+
// Draw to screen
|
127
122
|
libsdl.symbols.SDL_RenderCopyEx(
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
ptr(
|
123
|
+
Renderer.pointer,
|
124
|
+
image.pointer,
|
125
|
+
null,
|
126
|
+
ptr(dstRect),
|
132
127
|
rotation ? rotation : 0,
|
133
|
-
ptr(_center),
|
134
|
-
flip ? Number(flip) : 0
|
135
|
-
);
|
136
|
-
}
|
137
|
-
|
138
|
-
/**
|
139
|
-
* Method to draw text to the screen
|
140
|
-
*
|
141
|
-
* @param text the string of text to print
|
142
|
-
* @param x x position
|
143
|
-
* @param y y position
|
144
|
-
* @param color color of text. Made using Slifer.Graphics.makeColor.
|
145
|
-
*/
|
146
|
-
print(text: string, x: number, y: number, color: Color) {
|
147
|
-
// Create text buffer
|
148
|
-
const textBuffer = Buffer.from(text + "\x00");
|
149
|
-
|
150
|
-
// Get width and height of text
|
151
|
-
const wArr = new Uint32Array(1);
|
152
|
-
const hArr = new Uint32Array(1);
|
153
|
-
libttf.symbols.TTF_SizeText(
|
154
|
-
Global.ptrFont,
|
155
|
-
textBuffer,
|
156
|
-
ptr(wArr),
|
157
|
-
ptr(hArr)
|
158
|
-
);
|
159
|
-
|
160
|
-
// Define color
|
161
|
-
const _col = (color.r << 0) + (color.g << 8) + (color.b << 16);
|
162
|
-
|
163
|
-
// Create texture
|
164
|
-
const surface = libttf.symbols.TTF_RenderText_Solid(
|
165
|
-
Global.ptrFont,
|
166
|
-
textBuffer,
|
167
|
-
_col
|
168
|
-
);
|
169
|
-
if (surface == null) throw `Surface creation failed on print`;
|
170
|
-
const texture = libsdl.symbols.SDL_CreateTextureFromSurface(
|
171
|
-
Global.ptrRenderer,
|
172
|
-
surface
|
173
|
-
);
|
174
|
-
if (texture == null) throw `Texture creation failed on print`;
|
175
|
-
|
176
|
-
// Create destination
|
177
|
-
const destArr = new Uint32Array(4);
|
178
|
-
destArr[0] = x;
|
179
|
-
destArr[1] = y;
|
180
|
-
destArr[2] = wArr[0];
|
181
|
-
destArr[3] = hArr[0];
|
182
|
-
|
183
|
-
// Draw text
|
184
|
-
libsdl.symbols.SDL_RenderCopy(
|
185
|
-
Global.ptrRenderer,
|
186
|
-
texture,
|
187
128
|
null,
|
188
|
-
|
189
|
-
);
|
190
|
-
}
|
191
|
-
|
192
|
-
/**
|
193
|
-
* Sets the font to a ttf file in your project
|
194
|
-
*
|
195
|
-
* @param path relative path to font
|
196
|
-
* @param pt size of text
|
197
|
-
*/
|
198
|
-
setFont(path: string, pt: number) {
|
199
|
-
const tempFont = libttf.symbols.TTF_OpenFont(
|
200
|
-
Buffer.from(path + "\x00"),
|
201
|
-
pt
|
129
|
+
null
|
202
130
|
);
|
203
|
-
if (tempFont == null) throw `Font loading failed`;
|
204
|
-
Global.ptrFont = tempFont;
|
205
131
|
}
|
206
132
|
}
|
207
133
|
|
208
134
|
class Image {
|
209
|
-
|
210
|
-
public readonly
|
211
|
-
public readonly height;
|
135
|
+
public readonly pointer: Pointer;
|
136
|
+
public readonly size: Vector2;
|
212
137
|
|
213
138
|
constructor(texture: Pointer) {
|
214
139
|
this.pointer = texture;
|
@@ -224,8 +149,7 @@ class Image {
|
|
224
149
|
ptr(_hArr)
|
225
150
|
);
|
226
151
|
|
227
|
-
this.
|
228
|
-
this.height = _hArr[0];
|
152
|
+
this.size = new Vector2(_wArr[0], _hArr[0]);
|
229
153
|
}
|
230
154
|
}
|
231
155
|
|
package/src/modules/keyboard.ts
CHANGED
@@ -1,34 +1,58 @@
|
|
1
|
+
import { libsdl } from "../ffi";
|
2
|
+
|
1
3
|
/** @internal */
|
2
4
|
class Keyboard {
|
5
|
+
static #instance: Keyboard;
|
3
6
|
|
4
7
|
static downKeyMap = new Map<string, boolean>();
|
5
8
|
static pressedKeyMap = new Map<string, boolean>();
|
6
9
|
static releasedKeyMap = new Map<string, boolean>();
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
|
11
|
+
private constructor() {}
|
12
|
+
|
13
|
+
public static get instance() {
|
14
|
+
if (!Keyboard.#instance) {
|
15
|
+
Keyboard.#instance = new Keyboard();
|
16
|
+
}
|
17
|
+
|
18
|
+
return Keyboard.#instance;
|
19
|
+
}
|
20
|
+
|
21
|
+
private static convertScancodeToKey(scancode: number): string {
|
22
|
+
const keyFromScancode = libsdl.symbols.SDL_GetKeyFromScancode(scancode);
|
23
|
+
const keyName = libsdl.symbols
|
24
|
+
.SDL_GetKeyName(keyFromScancode)
|
25
|
+
.toString();
|
26
|
+
|
27
|
+
return keyName;
|
28
|
+
}
|
29
|
+
|
30
|
+
static setKeyDown(key: number): void {
|
31
|
+
const keyName = Keyboard.convertScancodeToKey(key);
|
32
|
+
this.downKeyMap.set(keyName.toLowerCase(), true);
|
33
|
+
this.releasedKeyMap.set(keyName.toLowerCase(), false);
|
11
34
|
}
|
12
35
|
|
13
|
-
static setKeyUp(key:
|
14
|
-
|
15
|
-
this.
|
36
|
+
static setKeyUp(key: number) {
|
37
|
+
const keyName = Keyboard.convertScancodeToKey(key);
|
38
|
+
this.downKeyMap.set(keyName.toLowerCase(), false);
|
39
|
+
this.pressedKeyMap.set(keyName.toLowerCase(), false);
|
16
40
|
}
|
17
41
|
|
18
42
|
/**
|
19
|
-
*
|
43
|
+
*
|
20
44
|
* @param key string of key
|
21
45
|
* @returns if the key is being held down
|
22
46
|
*/
|
23
47
|
isDown(key: keys) {
|
24
48
|
const _state = Keyboard.downKeyMap.get(key);
|
25
|
-
if (_state == undefined) return false
|
49
|
+
if (_state == undefined) return false;
|
26
50
|
|
27
51
|
return _state;
|
28
52
|
}
|
29
53
|
|
30
54
|
/**
|
31
|
-
*
|
55
|
+
*
|
32
56
|
* @param key string of key
|
33
57
|
* @returns if key is pressed. Returns only once
|
34
58
|
*/
|
@@ -47,7 +71,7 @@ class Keyboard {
|
|
47
71
|
}
|
48
72
|
|
49
73
|
/**
|
50
|
-
*
|
74
|
+
*
|
51
75
|
* @param key string of key
|
52
76
|
* @returns if key is released. Returns only once
|
53
77
|
*/
|
@@ -66,15 +90,50 @@ class Keyboard {
|
|
66
90
|
}
|
67
91
|
}
|
68
92
|
|
69
|
-
type keys =
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
93
|
+
type keys =
|
94
|
+
| "a"
|
95
|
+
| "b"
|
96
|
+
| "c"
|
97
|
+
| "d"
|
98
|
+
| "e"
|
99
|
+
| "f"
|
100
|
+
| "g"
|
101
|
+
| "h"
|
102
|
+
| "i"
|
103
|
+
| "j"
|
104
|
+
| "k"
|
105
|
+
| "l"
|
106
|
+
| "m"
|
107
|
+
| "n"
|
108
|
+
| "o"
|
109
|
+
| "p"
|
110
|
+
| "q"
|
111
|
+
| "r"
|
112
|
+
| "s"
|
113
|
+
| "t"
|
114
|
+
| "u"
|
115
|
+
| "v"
|
116
|
+
| "w"
|
117
|
+
| "x"
|
118
|
+
| "y"
|
119
|
+
| "z"
|
120
|
+
| "1"
|
121
|
+
| "2"
|
122
|
+
| "3"
|
123
|
+
| "4"
|
124
|
+
| "5"
|
125
|
+
| "6"
|
126
|
+
| "7"
|
127
|
+
| "8"
|
128
|
+
| "9"
|
129
|
+
| "0"
|
130
|
+
| "space"
|
131
|
+
| "caps lock"
|
132
|
+
| "tab"
|
133
|
+
| "left shift"
|
134
|
+
| "right shift"
|
135
|
+
| "left ctrl"
|
136
|
+
| "escape";
|
78
137
|
|
79
138
|
/** @internal */
|
80
|
-
export default Keyboard;
|
139
|
+
export default Keyboard;
|
package/src/modules/mouse.ts
CHANGED
@@ -1,16 +1,25 @@
|
|
1
1
|
import { libsdl } from "../ffi";
|
2
|
-
import { ptr } from
|
2
|
+
import { ptr } from "bun:ffi";
|
3
|
+
import Vector2 from "../engine/vector";
|
3
4
|
|
4
5
|
/** @internal */
|
5
6
|
class Mouse {
|
7
|
+
static #instance: Mouse;
|
6
8
|
|
7
9
|
static downKeyMap = new Map<string, boolean>();
|
8
10
|
static pressedKeyMap = new Map<string, boolean>();
|
9
11
|
static releasedKeyMap = new Map<string, boolean>();
|
10
|
-
|
11
|
-
static setButtonDown(button: number) {
|
12
12
|
|
13
|
-
|
13
|
+
private constructor() {}
|
14
|
+
|
15
|
+
public static get instance() {
|
16
|
+
if (!Mouse.#instance) Mouse.#instance = new Mouse();
|
17
|
+
|
18
|
+
return Mouse.#instance;
|
19
|
+
}
|
20
|
+
|
21
|
+
static setButtonDown(button: number) {
|
22
|
+
let key: string = "";
|
14
23
|
if (button == 1) {
|
15
24
|
key = "left";
|
16
25
|
} else if (button == 2) {
|
@@ -24,8 +33,7 @@ class Mouse {
|
|
24
33
|
}
|
25
34
|
|
26
35
|
static setButtonUp(button: number) {
|
27
|
-
|
28
|
-
let key : string = '';
|
36
|
+
let key: string = "";
|
29
37
|
if (button == 1) {
|
30
38
|
key = "left";
|
31
39
|
} else if (button == 2) {
|
@@ -33,25 +41,25 @@ class Mouse {
|
|
33
41
|
} else {
|
34
42
|
key = "right";
|
35
43
|
}
|
36
|
-
|
44
|
+
|
37
45
|
this.downKeyMap.set(key, false);
|
38
46
|
this.pressedKeyMap.set(key, false);
|
39
47
|
}
|
40
48
|
|
41
49
|
/**
|
42
|
-
*
|
50
|
+
*
|
43
51
|
* @param button string of button
|
44
52
|
* @returns if the button is being held down
|
45
53
|
*/
|
46
54
|
isDown(button: buttons) {
|
47
55
|
const _state = Mouse.downKeyMap.get(button);
|
48
|
-
if (_state == undefined) return false
|
56
|
+
if (_state == undefined) return false;
|
49
57
|
|
50
58
|
return _state;
|
51
59
|
}
|
52
60
|
|
53
61
|
/**
|
54
|
-
*
|
62
|
+
*
|
55
63
|
* @param button string of button
|
56
64
|
* @returns if button is pressed. Returns only once
|
57
65
|
*/
|
@@ -70,7 +78,7 @@ class Mouse {
|
|
70
78
|
}
|
71
79
|
|
72
80
|
/**
|
73
|
-
*
|
81
|
+
*
|
74
82
|
* @param button string of button
|
75
83
|
* @returns if button is released. Returns only once
|
76
84
|
*/
|
@@ -92,11 +100,11 @@ class Mouse {
|
|
92
100
|
const xArr = new Uint32Array(1);
|
93
101
|
const yArr = new Uint32Array(1);
|
94
102
|
libsdl.symbols.SDL_GetMouseState(ptr(xArr), ptr(yArr));
|
95
|
-
return
|
103
|
+
return new Vector2(xArr[0], yArr[0]);
|
96
104
|
}
|
97
105
|
}
|
98
106
|
|
99
|
-
type buttons =
|
107
|
+
type buttons = "left" | "middle" | "right";
|
100
108
|
|
101
109
|
/** @internal */
|
102
|
-
export default Mouse;
|
110
|
+
export default Mouse;
|
package/src/slifer.test.ts
CHANGED
@@ -1,8 +1,43 @@
|
|
1
1
|
import { describe, expect, it } from "bun:test";
|
2
|
-
import {
|
2
|
+
import { initSDL, initSDLImage, initSDLTypeFont, initSDLMixer } from "./engine";
|
3
|
+
import Vector2 from "./engine/vector";
|
4
|
+
import Window from "./engine/window";
|
5
|
+
import Renderer from "./engine/renderer";
|
3
6
|
|
4
|
-
describe("Initializing ", () => {
|
7
|
+
describe("Initializing SDL ", () => {
|
5
8
|
it("Should initialize without error ", () => {
|
6
|
-
expect(() =>
|
9
|
+
expect(() => initSDL()).not.toThrow(Error);
|
10
|
+
});
|
11
|
+
});
|
12
|
+
|
13
|
+
describe("Initializing SDL Image ", () => {
|
14
|
+
it("Should initialize without error ", () => {
|
15
|
+
expect(() => initSDLImage()).not.toThrow(Error);
|
16
|
+
});
|
17
|
+
});
|
18
|
+
|
19
|
+
describe("Initializing SDL TTF ", () => {
|
20
|
+
it("Should initialize without error ", () => {
|
21
|
+
expect(() => initSDLTypeFont()).not.toThrow(Error);
|
22
|
+
});
|
23
|
+
});
|
24
|
+
|
25
|
+
describe("Initializing SDL Mixer ", () => {
|
26
|
+
it("Should initialize without error ", () => {
|
27
|
+
expect(() => initSDLMixer()).not.toThrow(Error);
|
28
|
+
});
|
29
|
+
});
|
30
|
+
|
31
|
+
describe("Window Creation ", () => {
|
32
|
+
it("Should create window without error", () => {
|
33
|
+
expect(() =>
|
34
|
+
Window.createWindow("Game", new Vector2(1, 1))
|
35
|
+
).not.toThrow(Error);
|
36
|
+
});
|
37
|
+
});
|
38
|
+
|
39
|
+
describe("Renderer Creation ", () => {
|
40
|
+
it("Should create renderer without error", () => {
|
41
|
+
expect(() => Renderer.createRenderer()).not.toThrow(Error);
|
7
42
|
});
|
8
43
|
});
|