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