]> git.bts.cx Git - benzene.git/blob - src/bz/scripting/bindings.cpp
Update git module URL
[benzene.git] / src / bz / scripting / bindings.cpp
1 #include <bz/scripting/bindings_internal.h>
2
3 #include <bz/game/scene_internal.h>
4 #include <bz/game/tilemap.h>
5 #include <bz/gfx/drawing.h>
6 //#include <bz/gfx/gfx.h>
7 #include <bz/gfx/tilemap.h>
8 #include <bz/input/input.h>
9 #include <bz/math/math.h>
10 #include <bz/math/random.h>
11
12 #include <stb_sprintf.h>
13
14 #include "static_crc32.hpp"
15
16 #define _FUNCTION_PARAMETER(idx,t) stack[idx].t##Literal
17 #define _FUNCTION_BINDING(n, f, ...) static void native_##n(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) { BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance); f( __VA_ARGS__ ); }
18 #define _FUNCTION_BINDING_RTN(n, f, ...) static void native_##n(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) { BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance); stack[0].__raw =  (int32_t)(f( __VA_ARGS__ )); }
19 #define _FUNCTION_BINDING_RTN_WRAP(n, f, ...) static void native_##n(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) { BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance); stack[0].__raw =  FIXED(f( __VA_ARGS__ )); }
20 #define _FUNCTION_BINDING_RTN_WRAP_FLOAT(n, f, ...) static void native_##n(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) { BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance); stack[0].__raw =  FIXED_FROM_FLOAT(f( __VA_ARGS__ )); }
21
22 #define _CONTEXT_PARAMETER(name) (metadata->name)
23
24 #define _RAW_PARAMETER(idx) stack[idx].__raw
25 #define _INT_PARAMETER(idx) FIXED_TO_INT(_FUNCTION_PARAMETER(idx, integer))
26 #define _FLOAT_PARAMETER(idx) FIXED_TO_FLOAT(_FUNCTION_PARAMETER(idx, integer))
27 #define _STRING_PARAMETER(idx) svmGetString(instance, _FUNCTION_PARAMETER(idx, pointer))
28
29 #define FUNCTION_BIND(n) case COMPILE_TIME_CRC32_STR(#n): return native_##n;
30
31 static void calculateTransformMatrix(BZScriptBindingMetadata *metadata) {
32         bzMatrixSRT(&metadata->matrix, metadata->position.x, metadata->position.y, metadata->angle, metadata->scale.x, metadata->scale.y);
33 }
34
35 static void resetTransform(BZScriptBindingMetadata *metadata) {
36         bzVectorSet(&metadata->position, 0, 0);
37         metadata->angle = 0.0f;
38         bzVectorSet(&metadata->scale, 1, 1);
39         //bzMatrixIdentity(&metadata->matrix);
40         calculateTransformMatrix(metadata);
41 }
42
43 void bzScriptingInitialiseMetadata(BZScriptBindingMetadata *metadata, BZActorID actor, BZSceneID scene, uint32_t uuid) {
44         *metadata = (BZScriptBindingMetadata) {
45                 .actor = actor,
46                 .scene = scene,
47                 .sortIdx = 0,
48                 .drawQueue = NULL,
49                 .uuid = uuid,
50         };
51         resetTransform(metadata);
52 }
53
54 _FUNCTION_BINDING(log, bzLog, "%s", svmGetString(instance, stack[1].pointerLiteral))
55
56 static void native_logf(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
57         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
58         const char *formatString = _STRING_PARAMETER(1);
59
60         char outputString[256]; // fixme
61         char *o = outputString;
62
63         size_t paramIdx = 2;
64
65         for (const char *f = formatString; *f != '\0'; ++f) {
66                 switch (*f) {
67                         case 's':
68                                 o += stbsp_sprintf(o, "%s", _STRING_PARAMETER(paramIdx++));
69                                 break;
70
71                         case 'd':
72                                 o += stbsp_sprintf(o, "%d", _INT_PARAMETER(paramIdx++));
73                                 break;
74                 }
75         }
76
77         bzLog("%s", outputString);
78 }
79
80 //_FUNCTION_BINDING(logNum, bzLog, "%f", FIXED_TO_FLOAT(stack[1].floatLiteral))
81
82 _FUNCTION_BINDING_RTN(sqrt, fixedSqrt, _FUNCTION_PARAMETER(1, float))
83 _FUNCTION_BINDING_RTN(sin, fixedSin, _FUNCTION_PARAMETER(1, float))
84 _FUNCTION_BINDING_RTN(cos, fixedCos, _FUNCTION_PARAMETER(1, float))
85 _FUNCTION_BINDING_RTN(atan2, fixedAtan2, _FUNCTION_PARAMETER(1, float), _FUNCTION_PARAMETER(2, float))
86 _FUNCTION_BINDING_RTN_WRAP_FLOAT(adelta, bzAngleDelta, _FLOAT_PARAMETER(1), _FLOAT_PARAMETER(2))
87
88 _FUNCTION_BINDING_RTN_WRAP_FLOAT(distance, bzDistance, _FLOAT_PARAMETER(1), _FLOAT_PARAMETER(2), _FLOAT_PARAMETER(3), _FLOAT_PARAMETER(4))
89 _FUNCTION_BINDING_RTN(distanceCheck, bzDistanceCheck, _FLOAT_PARAMETER(1), _FLOAT_PARAMETER(2), _FLOAT_PARAMETER(3), _FLOAT_PARAMETER(4), _FLOAT_PARAMETER(5))
90
91 _FUNCTION_BINDING_RTN(min, fixedMin, _FUNCTION_PARAMETER(1, float), _FUNCTION_PARAMETER(2, float))
92 _FUNCTION_BINDING_RTN(max, fixedMax, _FUNCTION_PARAMETER(1, float), _FUNCTION_PARAMETER(2, float))
93 _FUNCTION_BINDING_RTN(mid, fixedMid, _FUNCTION_PARAMETER(1, float), _FUNCTION_PARAMETER(2, float), _FUNCTION_PARAMETER(3, float))
94 _FUNCTION_BINDING_RTN(sgn, fixedSgn, _FUNCTION_PARAMETER(1, float))
95 _FUNCTION_BINDING_RTN(abs, fixedAbs, _FUNCTION_PARAMETER(1, float))
96 _FUNCTION_BINDING_RTN(floor, fixedFloor, _FUNCTION_PARAMETER(1, float))
97 _FUNCTION_BINDING_RTN(ceil, fixedCeil, _FUNCTION_PARAMETER(1, float))
98
99 static void native_rnd(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
100         switch (parameterCount) {
101                 case 0:
102                         stack[0].__raw = FIXED_FROM_FLOAT(bzRandomFloat(1));
103                         break;
104
105                 case 1:
106                         stack[0].__raw = FIXED_FROM_FLOAT(bzRandomFloat(_FLOAT_PARAMETER(1)));
107                         break;
108
109                 default:
110                         stack[0].__raw = FIXED_FROM_FLOAT(bzRandomFloatRange(_FLOAT_PARAMETER(1), _FLOAT_PARAMETER(2)));
111                         break;
112         }
113 }
114
115 _FUNCTION_BINDING(srand, bzRandomReseed, _INT_PARAMETER(1))
116
117 _FUNCTION_BINDING_RTN(lerp, fixedLerp, _FUNCTION_PARAMETER(1, float), _FUNCTION_PARAMETER(2, float), _FUNCTION_PARAMETER(3, float))
118
119 static void native_dot(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
120         BZVector v1 = bzVectorMake(_FLOAT_PARAMETER(1), _FLOAT_PARAMETER(2));
121         BZVector v2 = bzVectorMake(_FLOAT_PARAMETER(3), _FLOAT_PARAMETER(4));
122         float dot = bzVectorDot(&v1, &v2);
123         stack[0].floatLiteral = FIXED_FROM_FLOAT(dot);
124 }
125
126 _FUNCTION_BINDING_RTN_WRAP_FLOAT(time, bzGameSceneGetTime, _CONTEXT_PARAMETER(scene))
127
128 //FUNCTION_BINDING_P4(clip, bzClip, integer, integer, integer, integer)
129 ////FUNCTION_BINDING_P3(pset, bzPSet, integer, integer, integer)
130 ////FUNCTION_BINDING_RTN_P2(sget, bzSGet, integer, integer)
131
132 _FUNCTION_BINDING(cls, bzDrawCls, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1))//FUNCTION_BINDING_P1(cls, bzDrawCls, integer)
133 _FUNCTION_BINDING(camera, bzDrawCamera, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2))//FUNCTION_BINDING_P2(camera, bzDrawCamera, integer, integer)
134 _FUNCTION_BINDING(circ, bzDrawCirc, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), _INT_PARAMETER(4))//FUNCTION_BINDING_P4(circ, bzDrawCirc, integer, integer, integer, integer)
135 _FUNCTION_BINDING(circfill, bzDrawCircFill, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), _INT_PARAMETER(4))//FUNCTION_BINDING_P4(circfill, bzDrawCircFill, integer, integer, integer, integer)
136 _FUNCTION_BINDING(line, bzDrawLine, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), _INT_PARAMETER(4), _INT_PARAMETER(5))//FUNCTION_BINDING_P5(line, bzDrawLine, integer, integer, integer, integer, integer)
137 _FUNCTION_BINDING(rect, bzDrawRect, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), _INT_PARAMETER(4), _INT_PARAMETER(5))//FUNCTION_BINDING_P5(rect, bzDrawRect, integer, integer, integer, integer, integer)
138 _FUNCTION_BINDING(rectfill, bzDrawRectFill, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), _INT_PARAMETER(4), _INT_PARAMETER(5))//FUNCTION_BINDING_P5(rectfill, bzDrawRectFill, integer, integer, integer, integer, integer)
139 _FUNCTION_BINDING(triangle, bzDrawTriangle, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), _INT_PARAMETER(4), _INT_PARAMETER(5), _INT_PARAMETER(6), _INT_PARAMETER(7))
140 //_FUNCTION_BINDING(spr, bzDrawSpr, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3))//FUNCTION_BINDING_P3(spr, bzDrawSpr, integer, integer, integer)
141 // spr ext
142 _FUNCTION_BINDING(sspr, bzDrawSSpr, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), _INT_PARAMETER(4), _INT_PARAMETER(5), _INT_PARAMETER(6))//FUNCTION_BINDING_P6(sspr, bzDrawSSpr, integer, integer, integer, integer, integer, integer)
143 // ext
144 _FUNCTION_BINDING(print, bzDrawPrint, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), _STRING_PARAMETER(4))
145 _FUNCTION_BINDING(fillp, bzDrawFillP, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _RAW_PARAMETER(1))//FUNCTION_BINDING_P1(fillp, bzDrawFillP, integer)
146 _FUNCTION_BINDING(palette, bzDrawSetPaletteColor, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3))//FUNCTION_BINDING_P3(palette, bzDrawSetPaletteColor, integer, integer, integer)
147 _FUNCTION_BINDING(output, bzDrawSetOutputBuffer, _CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1)) //FUNCTION_BINDING_P1(output, bzSetOutputBuffer, integer)
148
149 static void native_printf(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
150         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
151         const char *formatString = _STRING_PARAMETER(4);
152
153         char outputString[256]; // fixme
154         char *o = outputString;
155
156         size_t paramIdx = 5;
157
158         for (const char *f = formatString; *f != '\0'; ++f) {
159                 switch (*f) {
160                         case 's':
161                                 o += stbsp_sprintf(o, "%s", _STRING_PARAMETER(paramIdx++));
162                                 break;
163
164                         case 'd':
165                                 o += stbsp_sprintf(o, "%d", _INT_PARAMETER(paramIdx++));
166                                 break;
167                 }
168         }
169
170         bzDrawPrint(_CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), outputString);
171 }
172
173 static void native_spr(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
174         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
175         int w = (parameterCount >= 4) ? _INT_PARAMETER(4) : 1;
176         int h = (parameterCount >= 5) ? _INT_PARAMETER(5) : 1;
177         bool flipX = (parameterCount >= 6) ? _INT_PARAMETER(6) : false;
178         bool flipY = (parameterCount >= 7) ? _INT_PARAMETER(7) : false;
179         bzDrawSprExt(_CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), w, h, flipX, flipY);
180 }
181
182 static void native_map(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
183         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
184         BZTilemapID tilemap = bzGameGetSceneLayerTilemap(_CONTEXT_PARAMETER(scene), _CONTEXT_PARAMETER(layer));
185         uint32_t mask = (parameterCount >= 7) ? bzGameCalculateTilemapFlagsMask(tilemap, parameterCount - 6, &stack[7].pointerLiteral) : 0;
186         bzDrawMap(_CONTEXT_PARAMETER(drawQueue), _CONTEXT_PARAMETER(sortIdx), &_CONTEXT_PARAMETER(matrix), tilemap, _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3), _INT_PARAMETER(4), _INT_PARAMETER(5), _INT_PARAMETER(6), mask);
187 }
188
189 _FUNCTION_BINDING_RTN_WRAP(mget, bzGameGetTilemapTile, bzGameGetSceneLayerTilemap(_CONTEXT_PARAMETER(scene), _CONTEXT_PARAMETER(layer)), _INT_PARAMETER(1), _INT_PARAMETER(2))
190 _FUNCTION_BINDING(mset, bzGameSetTilemapTile, bzGameGetSceneLayerTilemap(_CONTEXT_PARAMETER(scene), _CONTEXT_PARAMETER(layer)), _INT_PARAMETER(1), _INT_PARAMETER(2), _INT_PARAMETER(3))
191 _FUNCTION_BINDING_RTN(mfget, bzGameGetTilemapHasFlag, bzGameGetSceneLayerTilemap(_CONTEXT_PARAMETER(scene), _CONTEXT_PARAMETER(layer)), _INT_PARAMETER(1), _INT_PARAMETER(2), _RAW_PARAMETER(3))
192
193 static void native_particle(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
194         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
195
196         BZVector position;
197         bzVectorCopy(&position, &_CONTEXT_PARAMETER(position));
198         float angle = _CONTEXT_PARAMETER(angle);
199
200         if (parameterCount >= 3) {
201                 position.x = _FLOAT_PARAMETER(2);
202                 position.y = _FLOAT_PARAMETER(3);
203         }
204
205         if (parameterCount >= 4) {
206                 angle = _FLOAT_PARAMETER(4);
207         }
208
209         size_t layerCount = bzGameGetSceneLayerCount(_CONTEXT_PARAMETER(scene));
210         for (size_t i = 0; i < layerCount; ++i) {
211                 BZSceneLayerID layer = bzGameGetSceneLayerAtIndex(_CONTEXT_PARAMETER(scene), i);
212                 BZParticleSimulationID simulation = bzGameGetSceneLayerParticleSimulation2(layer);
213                 if (simulation != NULL) {
214                         bzFXSpawnParticles(simulation, stack[1].pointerLiteral, &position, angle);
215                 }
216         }
217 }
218
219 static void native_sound(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
220         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
221         BZAudioPlaybackEngineID audioPlaybackEngine = bzGameGetAudioPlaybackEngine(_CONTEXT_PARAMETER(scene));
222         bzAudioPlaybackPostEvent(audioPlaybackEngine, stack[1].pointerLiteral);
223 }
224
225 static void native_speech(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
226         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
227         BZAudioPlaybackEngineID audioPlaybackEngine = bzGameGetAudioPlaybackEngine(_CONTEXT_PARAMETER(scene));
228         bzAudioPlaybackPostEvent(audioPlaybackEngine, stack[1].pointerLiteral, _STRING_PARAMETER(2));
229 }
230
231 static void native_speechf(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
232         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
233         const char *formatString = _STRING_PARAMETER(2);
234
235         char outputString[256]; // fixme
236         char *o = outputString;
237
238         size_t paramIdx = 3;
239
240         for (const char *f = formatString; *f != '\0'; ++f) {
241                 switch (*f) {
242                         case 's':
243                                 o += stbsp_sprintf(o, "%s", _STRING_PARAMETER(paramIdx++));
244                                 break;
245
246                         case 'd':
247                                 o += stbsp_sprintf(o, "%d", _INT_PARAMETER(paramIdx++));
248                                 break;
249                 }
250         }
251
252         BZAudioPlaybackEngineID audioPlaybackEngine = bzGameGetAudioPlaybackEngine(_CONTEXT_PARAMETER(scene));
253         bzAudioPlaybackPostEvent(audioPlaybackEngine, stack[1].pointerLiteral, outputString);
254 }
255
256 static void native_collision(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
257         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
258         BZCollisionSpaceID space = bzGameGetSceneLayerCollisionSpace(_CONTEXT_PARAMETER(scene), _CONTEXT_PARAMETER(layer));
259         
260         bzAssert(space != NULL);
261         
262         BZCollisionShape shape;
263         BZIdentifierHash tagHash;
264         switch (stack[1].pointerLiteral) {
265                 case COMPILE_TIME_CRC32_STR("circle"):
266                         shape = {
267                                 .type = BZCollisionShapeTypeCircle,
268                                 .circleOrigin = bzVectorMake(_FLOAT_PARAMETER(2), _FLOAT_PARAMETER(3)),
269                                 .circleRadius = _FLOAT_PARAMETER(4),
270                         };
271                         bzMatrixTransformVector(&shape.circleOrigin, &shape.circleOrigin, &_CONTEXT_PARAMETER(matrix));
272                         // FIXME, radius
273                         tagHash = _RAW_PARAMETER(5);
274                         break;
275                 
276                 case COMPILE_TIME_CRC32_STR("circlePerimeter"):
277                         shape = {
278                                 .type = BZCollisionShapeTypeCirclePerimeter,
279                                 .circleOrigin = bzVectorMake(_FLOAT_PARAMETER(2), _FLOAT_PARAMETER(3)),
280                                 .circleRadius = _FLOAT_PARAMETER(4),
281                         };
282                         bzMatrixTransformVector(&shape.circleOrigin, &shape.circleOrigin, &_CONTEXT_PARAMETER(matrix));
283                         // FIXME, radius
284                         tagHash = _RAW_PARAMETER(5);
285                         break;
286
287                 case COMPILE_TIME_CRC32_STR("triangle"):
288                         shape = {
289                                 .type = BZCollisionShapeTypeTriangle,
290                                 .trianglePoint1 = bzVectorMake(_FLOAT_PARAMETER(2), _FLOAT_PARAMETER(3)),
291                                 .trianglePoint2 = bzVectorMake(_FLOAT_PARAMETER(4), _FLOAT_PARAMETER(5)),
292                                 .trianglePoint3 = bzVectorMake(_FLOAT_PARAMETER(6), _FLOAT_PARAMETER(7)),
293                         };
294                         bzMatrixTransformVector(&shape.trianglePoint1, &shape.trianglePoint1, &_CONTEXT_PARAMETER(matrix));
295                         bzMatrixTransformVector(&shape.trianglePoint2, &shape.trianglePoint2, &_CONTEXT_PARAMETER(matrix));
296                         bzMatrixTransformVector(&shape.trianglePoint3, &shape.trianglePoint3, &_CONTEXT_PARAMETER(matrix));
297                         tagHash = _RAW_PARAMETER(8);
298                         break;
299         }
300
301         bzCollisionAddBody(space, BZCollisionBodyTypeSolid, &shape, tagHash, instance);
302 }
303
304 static void native_collisionCheck(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
305         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
306         //BZCollisionSpaceID space = bzGameGetSceneLayerCollisionSpace(_CONTEXT_PARAMETER(scene), _CONTEXT_PARAMETER(layer));
307
308         //bzAssert(space != NULL);
309
310         bool getOutput = true; // FIXME FIXME FIXME, this should only return when we need it?
311         bool removeParticles = true;
312
313         BZCollisionShape shape;
314         BZIdentifierHash tagHash;
315         switch (stack[1].pointerLiteral) {
316                 case COMPILE_TIME_CRC32_STR("circle"):
317                         shape = {
318                                 .type = BZCollisionShapeTypeCircle,
319                                 .circleOrigin = bzVectorMake(_FLOAT_PARAMETER(2), _FLOAT_PARAMETER(3)),
320                                 .circleRadius = _FLOAT_PARAMETER(4),
321                         };
322                         bzMatrixTransformVector(&shape.circleOrigin, &shape.circleOrigin, &_CONTEXT_PARAMETER(matrix));
323                         // FIXME, radius
324                         tagHash = _RAW_PARAMETER(5);
325                         if (parameterCount >= 6) removeParticles = _INT_PARAMETER(6) != 0;
326                         break;
327
328                 case COMPILE_TIME_CRC32_STR("circlePerimeter"):
329                         shape = {
330                                 .type = BZCollisionShapeTypeCirclePerimeter,
331                                 .circleOrigin = bzVectorMake(_FLOAT_PARAMETER(2), _FLOAT_PARAMETER(3)),
332                                 .circleRadius = _FLOAT_PARAMETER(4),
333                         };
334                         bzMatrixTransformVector(&shape.circleOrigin, &shape.circleOrigin, &_CONTEXT_PARAMETER(matrix));
335                         // FIXME, radius
336                         tagHash = _RAW_PARAMETER(5);
337                         if (parameterCount >= 6) removeParticles = _INT_PARAMETER(6) != 0;
338                         break;
339
340                 case COMPILE_TIME_CRC32_STR("triangle"):
341                         shape = {
342                                 .type = BZCollisionShapeTypeTriangle,
343                                 .trianglePoint1 = bzVectorMake(_FLOAT_PARAMETER(2), _FLOAT_PARAMETER(3)),
344                                 .trianglePoint2 = bzVectorMake(_FLOAT_PARAMETER(4), _FLOAT_PARAMETER(5)),
345                                 .trianglePoint3 = bzVectorMake(_FLOAT_PARAMETER(6), _FLOAT_PARAMETER(7)),
346                         };
347                         bzMatrixTransformVector(&shape.trianglePoint1, &shape.trianglePoint1, &_CONTEXT_PARAMETER(matrix));
348                         bzMatrixTransformVector(&shape.trianglePoint2, &shape.trianglePoint2, &_CONTEXT_PARAMETER(matrix));
349                         bzMatrixTransformVector(&shape.trianglePoint3, &shape.trianglePoint3, &_CONTEXT_PARAMETER(matrix));
350                         tagHash = _RAW_PARAMETER(8);
351                         if (parameterCount >= 9) removeParticles = _INT_PARAMETER(9) != 0;
352                         break;
353         }
354
355         stack[0].__raw = 0;
356
357         size_t layerCount = bzGameGetSceneLayerCount(_CONTEXT_PARAMETER(scene));
358         for (size_t i = 0; i < layerCount; ++i) {
359                 BZSceneLayerID layer = bzGameGetSceneLayerAtIndex(_CONTEXT_PARAMETER(scene), i);
360                 BZCollisionSpaceID space = bzGameGetSceneLayerCollisionSpace2(layer);
361                 if (space != NULL) {
362                         void *userParameter;
363                         
364                         if (getOutput) { // FIXME FIXME FIXME
365                                 BZVector out;
366                                 stack[0].__raw = bzCollisionResolve(&out, &userParameter, space, &shape, tagHash);
367
368                                 // FIXME: This is terrible
369                                 bzScriptingSetEnvironmentPublic(_CONTEXT_PARAMETER(scene), COMPILE_TIME_CRC32_STR("collisionX"), { .floatLiteral = FIXED_FROM_FLOAT(out.x) });
370                                 bzScriptingSetEnvironmentPublic(_CONTEXT_PARAMETER(scene), COMPILE_TIME_CRC32_STR("collisionY"), { .floatLiteral = FIXED_FROM_FLOAT(out.y) });
371                         } else {
372                                 stack[0].__raw = bzCollisionResolve(NULL, &userParameter, space, &shape, tagHash);
373                         }
374
375                         if (stack[0].__raw) {
376                                 if (removeParticles) {
377                                         BZParticleSimulationID particleSimulation = bzGameGetSceneLayerParticleSimulation2(layer);
378                                         if (particleSimulation != NULL) {
379                                                 bzFXDespawnParticle(particleSimulation, (size_t)userParameter);
380                                         }
381                                 }
382                                 break;
383                         }
384                 }
385         }
386 }
387
388 #include <bz/game/actor_internal.h>
389 static void native_actor(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
390         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
391         BZActorID actor = bzGameSceneAddActor(_CONTEXT_PARAMETER(scene), "%s", svmGetString(instance, stack[1].pointerLiteral));
392         for (size_t i = 2, j = 1; i <= parameterCount; ++i, ++j) {
393                 actor->parameters[j] = stack[i].__raw;
394         }
395 }
396
397 static void native_find(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
398         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
399         BZActorID actor = bzGameSceneFindActor(_CONTEXT_PARAMETER(scene), "%s", svmGetString(instance, stack[1].pointerLiteral));
400         stack[0].pointerLiteral = actor->identifierHash; // FIXME, use idx or something...
401 }
402
403 static void native_parameter(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
404         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
405         stack[0].__raw = _CONTEXT_PARAMETER(actor)->parameters[FIXED_TO_INT(stack[1].integerLiteral)];
406 }
407
408 #include <bz/scripting/environment_internal.h>
409 #include <bz/scripting/script_internal.h>
410 static void native_public(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
411         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
412
413         if (parameterCount >= 2) {
414                 bzScriptingSetEnvironmentPublic(_CONTEXT_PARAMETER(scene), stack[1].pointerLiteral, stack[2]);
415                 stack[0] = stack[2];
416         } else {
417                 if (bzScriptingGetEnvironmentPublic(&stack[0], _CONTEXT_PARAMETER(scene), stack[1].pointerLiteral) == false) {
418                         stack[0].__raw = 0;
419                 }
420         }
421 }
422
423 static void native_btn(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
424         switch (stack[1].pointerLiteral) {
425                 case COMPILE_TIME_CRC32_STR("up"):
426                         stack[0].__raw = bzInputBtn(1) ? 1 : 0;
427                         break;
428                 
429                 case COMPILE_TIME_CRC32_STR("down"):
430                         stack[0].__raw = bzInputBtn(2) ? 1 : 0;
431                         break;
432
433                 case COMPILE_TIME_CRC32_STR("left"):
434                         stack[0].__raw = bzInputBtn(3) ? 1 : 0;
435                         break;
436
437                 case COMPILE_TIME_CRC32_STR("right"):
438                         stack[0].__raw = bzInputBtn(4) ? 1 : 0;
439                         break;
440
441                 case COMPILE_TIME_CRC32_STR("action1"):
442                         stack[0].__raw = bzInputBtn(5) ? 1 : 0;
443                         break;
444
445                 case COMPILE_TIME_CRC32_STR("action2"):
446                         stack[0].__raw = bzInputBtn(6) ? 1 : 0;
447                         break;
448
449                 case COMPILE_TIME_CRC32_STR("alpha-up"):
450                         stack[0].__raw = bzInputBtn(7) ? 1 : 0;
451                         break;
452                 
453                 case COMPILE_TIME_CRC32_STR("alpha-down"):
454                         stack[0].__raw = bzInputBtn(8) ? 1 : 0;
455                         break;
456
457                 case COMPILE_TIME_CRC32_STR("alpha-left"):
458                         stack[0].__raw = bzInputBtn(9) ? 1 : 0;
459                         break;
460
461                 case COMPILE_TIME_CRC32_STR("alpha-right"):
462                         stack[0].__raw = bzInputBtn(10) ? 1 : 0;
463                         break;
464
465                 default:
466                         // Warn about button??
467                         stack[0].__raw = 0;
468                         break;
469         }
470 }
471
472 static void native_btnp(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
473         switch (stack[1].pointerLiteral) {
474                 case COMPILE_TIME_CRC32_STR("up"):
475                         stack[0].__raw = bzInputBtnP(1) ? 1 : 0;
476                         break;
477                 
478                 case COMPILE_TIME_CRC32_STR("down"):
479                         stack[0].__raw = bzInputBtnP(2) ? 1 : 0;
480                         break;
481
482                 case COMPILE_TIME_CRC32_STR("left"):
483                         stack[0].__raw = bzInputBtnP(3) ? 1 : 0;
484                         break;
485
486                 case COMPILE_TIME_CRC32_STR("right"):
487                         stack[0].__raw = bzInputBtnP(4) ? 1 : 0;
488                         break;
489
490                 case COMPILE_TIME_CRC32_STR("action1"):
491                         stack[0].__raw = bzInputBtnP(5) ? 1 : 0;
492                         break;
493
494                 case COMPILE_TIME_CRC32_STR("action2"):
495                         stack[0].__raw = bzInputBtnP(6) ? 1 : 0;
496                         break;
497
498                 case COMPILE_TIME_CRC32_STR("alpha-up"):
499                         stack[0].__raw = bzInputBtnP(7) ? 1 : 0;
500                         break;
501                 
502                 case COMPILE_TIME_CRC32_STR("alpha-down"):
503                         stack[0].__raw = bzInputBtnP(8) ? 1 : 0;
504                         break;
505
506                 case COMPILE_TIME_CRC32_STR("alpha-left"):
507                         stack[0].__raw = bzInputBtnP(9) ? 1 : 0;
508                         break;
509
510                 case COMPILE_TIME_CRC32_STR("alpha-right"):
511                         stack[0].__raw = bzInputBtnP(10) ? 1 : 0;
512                         break;
513
514                 default:
515                         // Warn about button??
516                         stack[0].__raw = 0;
517                         break;
518         }
519 }
520
521 static void native_depth(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
522         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
523         _CONTEXT_PARAMETER(sortIdx) = FIXED_TO_INT(stack[1].integerLiteral);
524 }
525
526 static void native_layer(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
527         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
528         _CONTEXT_PARAMETER(layer) = stack[1].pointerLiteral;
529         _CONTEXT_PARAMETER(drawQueue) = bzGameGetSceneLayerDrawQueue(_CONTEXT_PARAMETER(scene), _CONTEXT_PARAMETER(layer));
530 }
531
532 static void native_resetMatrix(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
533         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
534         resetTransform(metadata);
535         //bzMatrixIdentity(&_CONTEXT_PARAMETER(matrix));
536 }
537
538 static void native_translate(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
539         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
540         _CONTEXT_PARAMETER(position).x += _FLOAT_PARAMETER(1);
541         _CONTEXT_PARAMETER(position).y += _FLOAT_PARAMETER(2);
542         calculateTransformMatrix(metadata);
543
544 //      BZMatrix m;
545 //      bzMatrixTranslation(&m, _FLOAT_PARAMETER(1), _FLOAT_PARAMETER(2));
546 //      bzMatrixMultiply(&_CONTEXT_PARAMETER(matrix), &_CONTEXT_PARAMETER(matrix), &m);
547 }
548
549 static void native_rotate(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
550         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
551         _CONTEXT_PARAMETER(angle) += _FLOAT_PARAMETER(1);
552         calculateTransformMatrix(metadata);
553 //      BZMatrix m;
554 //      bzMatrixRotation(&m, _FLOAT_PARAMETER(1));
555 //      bzMatrixMultiply(&_CONTEXT_PARAMETER(matrix), &_CONTEXT_PARAMETER(matrix), &m);
556 }
557
558 static void native_scale(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
559         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
560         _CONTEXT_PARAMETER(scale).x *= _FLOAT_PARAMETER(1);
561         if (parameterCount == 1) {
562                 _CONTEXT_PARAMETER(scale).y *= _FLOAT_PARAMETER(1);
563         } else {
564                 _CONTEXT_PARAMETER(scale).y *= _FLOAT_PARAMETER(2);
565         }
566         calculateTransformMatrix(metadata);
567         
568         //BZMatrix m;
569         //if (parameterCount == 1) {
570         //      bzMatrixScale(&m, _FLOAT_PARAMETER(1), _FLOAT_PARAMETER(1));
571         //} else {
572         //      bzMatrixScale(&m, _FLOAT_PARAMETER(1), _FLOAT_PARAMETER(2));
573         //}
574         //bzMatrixMultiply(&_CONTEXT_PARAMETER(matrix), &_CONTEXT_PARAMETER(matrix), &m);
575 }
576
577 static void native_event(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
578         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
579         
580         if (parameterCount == 1) {
581                 bzGameScenePostEvent(_CONTEXT_PARAMETER(scene), _RAW_PARAMETER(1), NULL);
582         } else if (parameterCount >= 2) {
583                 BZSceneEventData data;
584                 data.integerValue = _RAW_PARAMETER(2);
585                 bzGameScenePostEvent(_CONTEXT_PARAMETER(scene), _RAW_PARAMETER(1), &data);
586         }
587 }
588
589 static void native_eventCheck(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
590         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
591         BZSceneEventData data;
592         bool found = bzGameSceneQueryEvent(&data, _CONTEXT_PARAMETER(scene), _RAW_PARAMETER(1));
593         if (found && parameterCount >= 2) {
594                 found = (data.integerValue == _RAW_PARAMETER(2));
595         }
596         stack[0].__raw = found ? 1 : 0;
597 }
598
599 /*static void native_agent(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
600         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
601         BZAgentSimulationID simulation = bzGameGetAgentSimulation(metadata->scene);
602
603         BZAgentDetails details = {
604                 .angle = metadata->angle,
605                 .mass = bzAgentDefaultMass,
606                 .maxForce = bzAgentDefaultMaxForce,
607                 .maxSpeed = bzAgentDefaultMaxSpeed,
608                 .position = metadata->position,
609         };
610
611         if (parameterCount >= 1) {
612                 details.position.x = _FLOAT_PARAMETER(1);
613         }
614         if (parameterCount >= 2) {
615                 details.position.y = _FLOAT_PARAMETER(2);
616         }
617         if (parameterCount >= 3) {
618                 details.angle = _FLOAT_PARAMETER(3);
619         }
620         if (parameterCount >= 4) {
621                 details.mass = _FLOAT_PARAMETER(4);
622         }
623         if (parameterCount >= 5) {
624                 details.maxForce = _FLOAT_PARAMETER(5);
625         }
626         if (parameterCount >= 6) {
627                 details.maxSpeed = _FLOAT_PARAMETER(6);
628         }
629
630         metadata->agent = bzFXAgentSimulationAddAgent(simulation, &details);
631 }
632
633 static void native_agentSync(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
634         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
635         BZAgentSimulationID simulation = bzGameGetAgentSimulation(metadata->scene);
636
637         BZAgentDetails details;
638         bzFXAgentSimulationGetAgentDetails(&details, simulation, metadata->agent);
639
640         metadata->angle = details.angle;
641         metadata->position = details.position;
642
643         calculateTransformMatrix(metadata);
644 }*/
645
646 static void native_scene(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
647         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
648         BZSceneEventData data = {
649                 .stringValue = _STRING_PARAMETER(1),
650         };
651         bzGameScenePostEvent(_CONTEXT_PARAMETER(scene), bzSceneChangeEventIdentifier, &data);
652
653 //      BZActorID actor = bzGameSceneAddActor(_CONTEXT_PARAMETER(scene), "%s", svmGetString(instance, stack[1].pointerLiteral));
654 //      for (size_t i = 2, j = 1; i <= parameterCount; ++i, ++j) {
655 //              actor->parameters[j] = stack[i].__raw;
656 //      }
657 }
658
659 static void native_id(SVMModuleInstance *instance, int32_t parameterCount, SVMOperand stack[]) {
660         BZScriptBindingMetadata *metadata = (BZScriptBindingMetadata *)svmGetModuleInstanceUserParameter(instance);
661         stack[0].__raw = metadata->uuid;
662 }
663
664 SVMFunctionCallback bzScriptingBindingsLookupNativeFunction(uint32_t nameCRC, void *userParam) {
665         switch (nameCRC) {
666                 FUNCTION_BIND(log)
667                 FUNCTION_BIND(logf)
668
669                 FUNCTION_BIND(btn)
670                 FUNCTION_BIND(btnp)
671
672                 FUNCTION_BIND(min)
673                 FUNCTION_BIND(max)
674                 FUNCTION_BIND(mid)
675                 FUNCTION_BIND(sgn)
676                 FUNCTION_BIND(abs)
677                 FUNCTION_BIND(floor)
678                 FUNCTION_BIND(ceil)
679                 FUNCTION_BIND(adelta)
680                 FUNCTION_BIND(rnd)
681                 FUNCTION_BIND(srand)
682                 FUNCTION_BIND(lerp)
683                 FUNCTION_BIND(dot)
684
685                 FUNCTION_BIND(time)
686
687                 FUNCTION_BIND(sqrt)
688                 FUNCTION_BIND(sin)
689                 FUNCTION_BIND(cos)
690                 FUNCTION_BIND(atan2)
691
692                 FUNCTION_BIND(distance)
693                 FUNCTION_BIND(distanceCheck)
694
695                 FUNCTION_BIND(layer)
696                 FUNCTION_BIND(depth)
697         //      FUNCTION_BIND(pset)
698         //      FUNCTION_BIND(sget)
699                 FUNCTION_BIND(cls)
700                 FUNCTION_BIND(camera)
701                 FUNCTION_BIND(circ)
702                 FUNCTION_BIND(circfill)
703                 FUNCTION_BIND(line)
704                 FUNCTION_BIND(rect)
705                 FUNCTION_BIND(rectfill)
706                 FUNCTION_BIND(triangle)
707                 FUNCTION_BIND(spr)
708                 FUNCTION_BIND(sspr)
709                 FUNCTION_BIND(print)
710                 FUNCTION_BIND(printf)
711                 FUNCTION_BIND(fillp)
712                 FUNCTION_BIND(palette)
713                 FUNCTION_BIND(output)
714                 FUNCTION_BIND(map)
715                 FUNCTION_BIND(mget)
716                 FUNCTION_BIND(mset)
717                 FUNCTION_BIND(mfget)
718
719                 FUNCTION_BIND(resetMatrix)
720                 FUNCTION_BIND(translate)
721                 FUNCTION_BIND(rotate)
722                 FUNCTION_BIND(scale)
723
724                 FUNCTION_BIND(particle)
725
726                 FUNCTION_BIND(sound)
727                 FUNCTION_BIND(speech)
728                 FUNCTION_BIND(speechf)
729
730                 FUNCTION_BIND(collision)
731                 FUNCTION_BIND(collisionCheck)
732
733                 FUNCTION_BIND(actor)
734                 FUNCTION_BIND(find)
735                 FUNCTION_BIND(parameter)
736                 FUNCTION_BIND(public)
737
738                 FUNCTION_BIND(event)
739                 FUNCTION_BIND(eventCheck)
740
741 //              FUNCTION_BIND(agent)
742 //              FUNCTION_BIND(agentSync)
743
744                 FUNCTION_BIND(scene)
745
746                 FUNCTION_BIND(id)
747
748                 default:
749                         bzLog("Warning: Could not find function %d", nameCRC);
750                         return NULL;
751         }
752 }