-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
grainboy.gr
146 lines (128 loc) · 2.89 KB
/
grainboy.gr
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
module Grainboy
include "runtime/unsafe/wasmi32"
include "runtime/unsafe/conv"
include "bytes"
// textPtr, textLen
foreign wasm log: (WasmI32, WasmI32) -> Void from "grainboy"
// x, y, font, color, textPtr, textLen
foreign wasm draw_text: (
WasmI32,
WasmI32,
WasmI32,
WasmI32,
WasmI32,
WasmI32,
) -> Void from "grainboy"
// x, y, width, height, fill
foreign wasm draw_rect: (
WasmI32,
WasmI32,
WasmI32,
WasmI32,
WasmI32,
) -> Void from "grainboy"
// x, y, diameter, fill
foreign wasm draw_circ: (
WasmI32,
WasmI32,
WasmI32,
WasmI32,
) -> Void from "grainboy"
// x, y, width, height, sx, sy
foreign wasm draw_sprite: (
WasmI32,
WasmI32,
WasmI32,
WasmI32,
WasmI32,
WasmI32,
) -> Void from "grainboy"
let inputBytes = Bytes.make(28 * 4) // gamepad size * num gamepads
@unsafe
provide let input = {
from WasmI32 use { (+) }
WasmI32.fromGrain(inputBytes) + 8n
}
provide enum InputState {
Released,
JustPressed,
Pressed,
JustReleased,
}
provide record Gamepad {
up: InputState,
down: InputState,
left: InputState,
right: InputState,
a: InputState,
b: InputState,
x: InputState,
y: InputState,
start: InputState,
select: InputState,
}
@unsafe
let u8ToInputState = n => {
match (n) {
0x0us => Released,
0x1us => JustPressed,
0x2us => Pressed,
0x3us => JustReleased,
_ => Released,
}
}
@unsafe
provide let gamepad = player => {
from WasmI32 use { (*) }
let i = Conv.wasmI32ToNumber(player * 10n)
{
up: u8ToInputState(Bytes.getUint8(i, inputBytes)),
down: u8ToInputState(Bytes.getUint8(i + 1, inputBytes)),
left: u8ToInputState(Bytes.getUint8(i + 2, inputBytes)),
right: u8ToInputState(Bytes.getUint8(i + 3, inputBytes)),
a: u8ToInputState(Bytes.getUint8(i + 4, inputBytes)),
b: u8ToInputState(Bytes.getUint8(i + 5, inputBytes)),
x: u8ToInputState(Bytes.getUint8(i + 6, inputBytes)),
y: u8ToInputState(Bytes.getUint8(i + 7, inputBytes)),
start: u8ToInputState(Bytes.getUint8(i + 8, inputBytes)),
select: u8ToInputState(Bytes.getUint8(i + 9, inputBytes)),
}
}
provide enum Font {
S,
M,
L,
}
@unsafe
provide let print = (text: String) => {
from WasmI32 use { (+) }
let ptr = WasmI32.fromGrain(text)
let textLen = WasmI32.load(ptr, 4n)
let textPtr = ptr + 8n
log(textPtr, textLen)
}
@unsafe
provide let text = (x, y, font, color, text: String) => {
from WasmI32 use { (+) }
let n = match (font) {
S => 0n,
M => 1n,
L => 2n,
}
let ptr = WasmI32.fromGrain(text)
let textLen = WasmI32.load(ptr, 4n)
let textPtr = ptr + 8n
draw_text(x, y, n, color, textPtr, textLen)
}
@unsafe
provide let rect = (x, y, width, height, color) => {
draw_rect(x, y, width, height, color)
}
@unsafe
provide let circ = (x, y, diameter, color) => {
draw_circ(x, y, diameter, color)
}
@unsafe
provide let sprite = (x, y, width, height, sx, sy) => {
draw_sprite(x, y, width, height, sx, sy)
}