diff --git a/Airport.vcxproj b/Airport.vcxproj
index ee0f36c..999d88a 100644
--- a/Airport.vcxproj
+++ b/Airport.vcxproj
@@ -28,6 +28,8 @@
+
+
diff --git a/assets/scripts/gameplay/lejana.toy b/assets/scripts/gameplay/lejana.toy
new file mode 100644
index 0000000..e51303a
--- /dev/null
+++ b/assets/scripts/gameplay/lejana.toy
@@ -0,0 +1,154 @@
+import node;
+
+//constants
+var SPEED: int const = 3;
+
+//variables
+var parent: opaque = null; //cache the parent for quick access
+var posX: int = 50;
+var posY: int = 50;
+var WIDTH: int const = 128;
+var HEIGHT: int const = 128;
+
+var xspeed: int = 0;
+var yspeed: int = 0;
+
+
+//polyfills - animating different cycles on one image
+var SPRITE_WIDTH: int const = 32;
+var SPRITE_HEIGHT: int const = 32;
+var stepCount: int = 0;
+var stepDelay: int = 10;
+
+fn faceDown(node: opaque) {
+ node.setNodeRect(0, 0, SPRITE_WIDTH, SPRITE_HEIGHT);
+ node.setNodeFrames(4);
+}
+
+fn faceUp(node: opaque) {
+ node.setNodeRect(32 * 4, 0, SPRITE_WIDTH, SPRITE_HEIGHT);
+ node.setNodeFrames(4);
+}
+
+fn faceLeft(node: opaque) {
+ node.setNodeRect(32 * 8, 0, SPRITE_WIDTH, SPRITE_HEIGHT);
+ node.setNodeFrames(4);
+}
+
+fn faceRight(node: opaque) {
+ node.setNodeRect(32 * 8, 0, SPRITE_WIDTH, SPRITE_HEIGHT);
+ node.setNodeFrames(4);
+}
+
+
+//lifecycle functions
+fn onLoad(node: opaque) {
+ //
+}
+
+fn onInit(node: opaque) {
+ parent = node.getParentNode();
+ node.loadTexture("sprites:/lejana.png");
+ node.faceDown();
+}
+
+fn onStep(node: opaque) {
+ posX += xspeed;
+ posY += yspeed;
+
+ //animate after X steps
+ if (xspeed == 0 && yspeed == 0) {
+ stepCount = 0;
+ node.setCurrentNodeFrame(0);
+ }
+ else {
+ if (++stepCount >= stepDelay) {
+ node.incrementCurrentNodeFrame();
+ stepCount = 0;
+ }
+ }
+}
+
+fn onFree(node: opaque) {
+ node.freeTexture();
+}
+
+fn onDraw(node: opaque) {
+ var px = 0;
+ var py = 0;
+
+ if (parent != null) {
+ px = parent.callNodeFn("getX");
+ py = parent.callNodeFn("getY");
+ }
+
+ node.drawNode(posX + px, posY + py, WIDTH, HEIGHT);
+}
+
+//event functions
+fn onKeyDown(node: opaque, event: string) {
+ if (event == "character_up") {
+ yspeed -= SPEED;
+ faceUp(node);
+ return;
+ }
+
+ if (event == "character_down") {
+ yspeed += SPEED;
+ faceDown(node);
+ return;
+ }
+
+ if (event == "character_left") {
+ xspeed -= SPEED;
+ faceLeft(node);
+ return;
+ }
+
+ if (event == "character_right") {
+ xspeed += SPEED;
+ faceRight(node);
+ return;
+ }
+}
+
+fn onKeyUp(node: opaque, event: string) {
+ if (event == "character_up" && yspeed < 0) {
+ yspeed = 0;
+ return;
+ }
+
+ if (event == "character_down" && yspeed > 0) {
+ yspeed = 0;
+ return;
+ }
+
+ if (event == "character_left" && xspeed < 0) {
+ xspeed = 0;
+ return;
+ }
+
+ if (event == "character_right" && xspeed > 0) {
+ xspeed = 0;
+ return;
+ }
+}
+
+fn onMouseMotion(node: opaque, x: int, y: int, xrel: int, yrel: int) {
+ //
+}
+
+fn onMouseButtonDown(node: opaque, x: int, y: int, button: string) {
+ //jump to pos
+ posX = x - WIDTH / 2;
+ posY = y - HEIGHT / 2;
+}
+
+fn onMouseButtonUp(node: opaque, x: int, y: int, button: string) {
+ //
+}
+
+fn onMouseWheel(node: opaque, xrel: int, yrel: int) {
+ //
+}
+
diff --git a/assets/scripts/gameplay/scene.toy b/assets/scripts/gameplay/scene.toy
new file mode 100644
index 0000000..e69de29
diff --git a/assets/scripts/init.toy b/assets/scripts/init.toy
index fc969ec..614326f 100644
--- a/assets/scripts/init.toy
+++ b/assets/scripts/init.toy
@@ -28,10 +28,10 @@
//this function must always be called, or the engine won't run
- initWindow("Airport Game", 1080, 720, false);
+ initWindow("Skyland", 1080, 720, false);
//kick off the logic of the scene graph
- loadRootNode("scripts:/demo/scene.toy");
+ loadRootNode("scripts:/gameplay/lejana.toy");
}
//Globals go here
diff --git a/assets/sprites/lejana.png b/assets/sprites/lejana.png
new file mode 100644
index 0000000..e1b279f
Binary files /dev/null and b/assets/sprites/lejana.png differ
diff --git a/box/box_engine.c b/box/box_engine.c
index 0c456bf..8d5cd30 100644
--- a/box/box_engine.c
+++ b/box/box_engine.c
@@ -146,8 +146,10 @@ static inline void execLoadRootNode() {
//immediately call onLoad() after running the script - for loading other nodes
Box_callEngineNode(engine.rootNode, &inner, "onLoad", NULL);
+ //cache the scope for later freeing
+ engine.rootNode->scope = inner.scope;
+
//manual cleanup
- Toy_popScope(inner.scope);
Toy_freeLiteralArray(&inner.stack);
Toy_freeLiteralArray(&inner.literalCache);
@@ -207,7 +209,7 @@ static inline void execEvents() {
//call the function
Toy_pushLiteralArray(&args, eventLiteral);
Box_callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onKeyDown", &args);
- Toy_popLiteralArray(&args);
+ Toy_freeLiteral(Toy_popLiteralArray(&args));
//push to the event list
Toy_freeLiteral(eventLiteral);
@@ -234,7 +236,7 @@ static inline void execEvents() {
//call the function
Toy_pushLiteralArray(&args, eventLiteral);
Box_callRecursiveEngineNode(engine.rootNode, &engine.interpreter, "onKeyUp", &args);
- Toy_popLiteralArray(&args);
+ Toy_freeLiteral(Toy_popLiteralArray(&args));
//push to the event list
Toy_freeLiteral(eventLiteral);
diff --git a/box/lib_engine.c b/box/lib_engine.c
index b2903af..e1e4cb0 100644
--- a/box/lib_engine.c
+++ b/box/lib_engine.c
@@ -86,7 +86,7 @@ static int nativeInitWindow(Toy_Interpreter* interpreter, Toy_LiteralArray* argu
printf("Renderer: %s (HW %s)\n", rendererInfo.name, rendererInfo.flags & SDL_RENDERER_ACCELERATED ? "yes" : "no");
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
+ SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
SDL_RenderSetLogicalSize(engine.renderer, engine.screenWidth, engine.screenHeight);
//only run with a window