Expanded keyboard API, added repl tools to make process
This commit is contained in:
@@ -51,3 +51,11 @@ modules.order
|
|||||||
Module.symvers
|
Module.symvers
|
||||||
Mkfile.old
|
Mkfile.old
|
||||||
dkms.conf
|
dkms.conf
|
||||||
|
|
||||||
|
#mdbook files
|
||||||
|
book
|
||||||
|
mdbook
|
||||||
|
|
||||||
|
#repl tools
|
||||||
|
source/*inspector*
|
||||||
|
source/*library*
|
||||||
+1
-1
Submodule Toy updated: bbb1e38649...b312c0d8a3
+28
-31
@@ -1,10 +1,11 @@
|
|||||||
//debug testing
|
//quick and dirty RNG
|
||||||
var counter = 0;
|
|
||||||
var randi: Int = 69420;
|
var randi: Int = 69420;
|
||||||
fn rand() {
|
fn rand() {
|
||||||
return randi = randi * 1664525 + 1013904223; //can be negative
|
return randi = randi * 1664525 + 1013904223; //overflows to a negative, which is fine
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//wander like a zombie
|
||||||
|
var counter = 0;
|
||||||
fn wander(actor: Opaque) {
|
fn wander(actor: Opaque) {
|
||||||
actor.setX(actor.x + rand() % 5);
|
actor.setX(actor.x + rand() % 5);
|
||||||
actor.setY(actor.y + rand() % 5);
|
actor.setY(actor.y + rand() % 5);
|
||||||
@@ -12,43 +13,36 @@ fn wander(actor: Opaque) {
|
|||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: general purpose math functions
|
|
||||||
//TODO: optimize away single-line blocks in the AST
|
|
||||||
|
|
||||||
//player controlled character
|
//player controlled character
|
||||||
var playerMaxMotion: Int = 5;
|
var playerMaxMotion: Int = 5;
|
||||||
var playerMotionX: Int = 0;
|
var playerMotionX: Int = 0;
|
||||||
var playerMotionY: Int = 0;
|
var playerMotionY: Int = 0;
|
||||||
|
|
||||||
fn playerOnFrame(player: Opaque) {
|
fn playerOnFrame(player: Opaque) {
|
||||||
//accept input
|
//handle keyboard input
|
||||||
if (Keyboard.UP) {
|
if (KeyPressed.UP) playerMotionY -= 5;
|
||||||
playerMotionY -= 5;
|
if (KeyPressed.DOWN) playerMotionY += 5;
|
||||||
}
|
if (KeyPressed.LEFT) playerMotionX -= 5;
|
||||||
if (Keyboard.DOWN) {
|
if (KeyPressed.RIGHT) playerMotionX += 5;
|
||||||
playerMotionY += 5;
|
|
||||||
}
|
|
||||||
if (Keyboard.LEFT) {
|
|
||||||
playerMotionX -= 5;
|
|
||||||
}
|
|
||||||
if (Keyboard.RIGHT) {
|
|
||||||
playerMotionX += 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
// print playerMotionX;
|
if (KeyReleased.UP) playerMotionY = min(playerMotionY + 5, 0);
|
||||||
// print playerMotionY;
|
if (KeyReleased.DOWN) playerMotionY = max(playerMotionY - 5, 0);
|
||||||
// print playerMaxMotion;
|
if (KeyReleased.LEFT) playerMotionX = min(playerMotionX + 5, 0);
|
||||||
// print -playerMaxMotion;
|
if (KeyReleased.RIGHT) playerMotionX = max(playerMotionX - 5, 0);
|
||||||
|
|
||||||
//cap the speed
|
//cap the max speed
|
||||||
if (playerMotionX > playerMaxMotion) playerMotionX = playerMaxMotion;
|
playerMotionX = min(max(playerMotionX, -playerMaxMotion), playerMaxMotion);
|
||||||
if (playerMotionX < -playerMaxMotion) playerMotionX = -playerMaxMotion;
|
playerMotionY = min(max(playerMotionY, -playerMaxMotion), playerMaxMotion);
|
||||||
if (playerMotionY > playerMaxMotion) playerMotionY = playerMaxMotion;
|
|
||||||
if (playerMotionY < -playerMaxMotion) playerMotionY = -playerMaxMotion;
|
//shortcut for normalized diagonal movement
|
||||||
|
var mod = 1;
|
||||||
|
if (playerMotionX != 0 && playerMotionY != 0) {
|
||||||
|
mod = 0.707;
|
||||||
|
}
|
||||||
|
|
||||||
//move the player
|
//move the player
|
||||||
player.setX(player.x + playerMotionX);
|
player.setX(player.x + floor(playerMotionX * mod));
|
||||||
player.setY(player.y + playerMotionY);
|
player.setY(player.y + floor(playerMotionY * mod));
|
||||||
}
|
}
|
||||||
|
|
||||||
//when the game is ready, load the "zombie" sprite
|
//when the game is ready, load the "zombie" sprite
|
||||||
@@ -68,9 +62,12 @@ fn onReady() {
|
|||||||
|
|
||||||
fn onFrame() {
|
fn onFrame() {
|
||||||
//debug
|
//debug
|
||||||
// print Keyboard.A;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//example API for the game
|
//example API for the game
|
||||||
initScreen(1280, 720, "Oh no, Zombies!");
|
initScreen(1280, 720, "Oh no, Zombies!");
|
||||||
initLoop(onReady, onFrame, null);
|
initLoop(onReady, onFrame, null);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//TODO: optimize away single-line blocks in the AST
|
||||||
@@ -17,7 +17,7 @@ export TOY_OUTDIR=../$(VAMP_OUTDIR)
|
|||||||
export TOY_OBJDIR=$(VAMP_OBJDIR)
|
export TOY_OBJDIR=$(VAMP_OBJDIR)
|
||||||
|
|
||||||
#targets
|
#targets
|
||||||
all: $(VAMP_OUTDIR) Toy source
|
all: $(VAMP_OUTDIR) Toy tools source
|
||||||
|
|
||||||
.PHONY: source
|
.PHONY: source
|
||||||
source:
|
source:
|
||||||
@@ -27,6 +27,11 @@ source:
|
|||||||
Toy:
|
Toy:
|
||||||
$(MAKE) -C $(TOY_SOURCEDIR)
|
$(MAKE) -C $(TOY_SOURCEDIR)
|
||||||
|
|
||||||
|
.PHONY: tools
|
||||||
|
tools:
|
||||||
|
cp Toy/repl/*library* $(VAMP_SOURCEDIR)
|
||||||
|
cp Toy/repl/*inspector* $(VAMP_SOURCEDIR)
|
||||||
|
|
||||||
#util targets
|
#util targets
|
||||||
$(VAMP_OUTDIR):
|
$(VAMP_OUTDIR):
|
||||||
mkdir $(VAMP_OUTDIR)
|
mkdir $(VAMP_OUTDIR)
|
||||||
|
|||||||
+15
-3
@@ -116,13 +116,25 @@ KeyboardMap keyboardMap[] = {
|
|||||||
{0, NULL},
|
{0, NULL},
|
||||||
};
|
};
|
||||||
|
|
||||||
KeyboardData keyboardData = { //NOTE: it is just a dummy struct right now so the API looks nice
|
KeyboardData keyboardData = {
|
||||||
.type = OPAQUE_KEYBOARD,
|
.type = OPAQUE_KEYBOARD,
|
||||||
|
.callback = &IsKeyDown,
|
||||||
|
};
|
||||||
|
|
||||||
|
KeyboardData keyPressedData = {
|
||||||
|
.type = OPAQUE_KEY_PRESSED,
|
||||||
|
.callback = &IsKeyPressed,
|
||||||
|
};
|
||||||
|
|
||||||
|
KeyboardData keyReleasedData = {
|
||||||
|
.type = OPAQUE_KEY_RELEASED,
|
||||||
|
.callback = &IsKeyReleased,
|
||||||
};
|
};
|
||||||
|
|
||||||
Toy_Value handleKeyboardAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
Toy_Value handleKeyboardAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
||||||
(void)vm;
|
(void)vm;
|
||||||
(void)compound;
|
|
||||||
|
KeyboardData* kd = (KeyboardData*)TOY_VALUE_AS_OPAQUE(compound);
|
||||||
|
|
||||||
Toy_String* string = TOY_VALUE_AS_STRING(attribute);
|
Toy_String* string = TOY_VALUE_AS_STRING(attribute);
|
||||||
const char* cstr = string->leaf.data;
|
const char* cstr = string->leaf.data;
|
||||||
@@ -130,7 +142,7 @@ Toy_Value handleKeyboardAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value att
|
|||||||
//find the mapped value, if available
|
//find the mapped value, if available
|
||||||
for (KeyboardMap* ptr = keyboardMap; ptr->cstr != NULL; ptr++) {
|
for (KeyboardMap* ptr = keyboardMap; ptr->cstr != NULL; ptr++) {
|
||||||
if (strlen(ptr->cstr) == strlen(cstr) && strncmp(cstr, ptr->cstr, strlen(ptr->cstr)) == 0) {
|
if (strlen(ptr->cstr) == strlen(cstr) && strncmp(cstr, ptr->cstr, strlen(ptr->cstr)) == 0) {
|
||||||
bool result = IsKeyPressed(ptr->raykey);
|
bool result = kd->callback(ptr->raykey);
|
||||||
return TOY_VALUE_FROM_BOOLEAN(result);
|
return TOY_VALUE_FROM_BOOLEAN(result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,9 @@
|
|||||||
#include "toy_vm.h"
|
#include "toy_vm.h"
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
|
|
||||||
|
//fn pointers
|
||||||
|
typedef bool (*raykey_callback)(int);
|
||||||
|
|
||||||
//wraps raylib's 'KeyboardKey' enum to a c-string
|
//wraps raylib's 'KeyboardKey' enum to a c-string
|
||||||
typedef struct KeyboardMap {
|
typedef struct KeyboardMap {
|
||||||
int raykey;
|
int raykey;
|
||||||
@@ -15,8 +18,11 @@ extern KeyboardMap keyboardMap[];
|
|||||||
//keyboard opaque
|
//keyboard opaque
|
||||||
typedef struct KeyboardData {
|
typedef struct KeyboardData {
|
||||||
OpaqueType type;
|
OpaqueType type;
|
||||||
|
raykey_callback callback;
|
||||||
} KeyboardData;
|
} KeyboardData;
|
||||||
|
|
||||||
extern KeyboardData keyboardData;
|
extern KeyboardData keyboardData;
|
||||||
|
extern KeyboardData keyPressedData;
|
||||||
|
extern KeyboardData keyReleasedData;
|
||||||
|
|
||||||
Toy_Value handleKeyboardAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute);
|
Toy_Value handleKeyboardAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute);
|
||||||
+24
-4
@@ -11,11 +11,14 @@
|
|||||||
#include "keyboard.h"
|
#include "keyboard.h"
|
||||||
#include "actor.h"
|
#include "actor.h"
|
||||||
|
|
||||||
|
#include "standard_library.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
// #include "bytecode_inspector.h"
|
// #include "bytecode_inspector.h"
|
||||||
|
// #include "bucket_inspector.h"
|
||||||
|
|
||||||
//utils
|
//utils
|
||||||
unsigned char* readFile(char* path, int* size) {
|
unsigned char* readFile(char* path, int* size) {
|
||||||
@@ -160,6 +163,8 @@ Toy_Value dispatchOpaqueAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value att
|
|||||||
|
|
||||||
switch(*type) {
|
switch(*type) {
|
||||||
case OPAQUE_KEYBOARD:
|
case OPAQUE_KEYBOARD:
|
||||||
|
case OPAQUE_KEY_PRESSED:
|
||||||
|
case OPAQUE_KEY_RELEASED:
|
||||||
return handleKeyboardAttributes(vm, compound, attribute);
|
return handleKeyboardAttributes(vm, compound, attribute);
|
||||||
|
|
||||||
case OPAQUE_ACTOR:
|
case OPAQUE_ACTOR:
|
||||||
@@ -197,10 +202,22 @@ void initGameAPI(Toy_VM* vm) {
|
|||||||
Toy_freeString(key);
|
Toy_freeString(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
//declare keyboard opaque
|
//declare input opaques
|
||||||
Toy_String* keyboardString = Toy_toString(&vm->memoryBucket, "Keyboard");
|
{
|
||||||
Toy_declareScope(vm->scope, keyboardString, TOY_VALUE_OPAQUE, TOY_OPAQUE_FROM_POINTER(&keyboardData), true);
|
Toy_String* name = Toy_toString(&vm->memoryBucket, "Keyboard");
|
||||||
Toy_freeString(keyboardString);
|
Toy_declareScope(vm->scope, name, TOY_VALUE_OPAQUE, TOY_OPAQUE_FROM_POINTER(&keyboardData), true);
|
||||||
|
Toy_freeString(name);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Toy_String* name = Toy_toString(&vm->memoryBucket, "KeyPressed");
|
||||||
|
Toy_declareScope(vm->scope, name, TOY_VALUE_OPAQUE, TOY_OPAQUE_FROM_POINTER(&keyPressedData), true);
|
||||||
|
Toy_freeString(name);
|
||||||
|
}
|
||||||
|
{
|
||||||
|
Toy_String* name = Toy_toString(&vm->memoryBucket, "KeyReleased");
|
||||||
|
Toy_declareScope(vm->scope, name, TOY_VALUE_OPAQUE, TOY_OPAQUE_FROM_POINTER(&keyReleasedData), true);
|
||||||
|
Toy_freeString(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//main file
|
//main file
|
||||||
@@ -221,6 +238,7 @@ int main() {
|
|||||||
Toy_initVM(&vm);
|
Toy_initVM(&vm);
|
||||||
Toy_bindVM(&vm, entryCode, NULL);
|
Toy_bindVM(&vm, entryCode, NULL);
|
||||||
|
|
||||||
|
initStandardLibrary(&vm);
|
||||||
initGameAPI(&vm);
|
initGameAPI(&vm);
|
||||||
initActorAPI(&vm);
|
initActorAPI(&vm);
|
||||||
Toy_setOpaqueAttributeHandler(dispatchOpaqueAttributes);
|
Toy_setOpaqueAttributeHandler(dispatchOpaqueAttributes);
|
||||||
@@ -271,6 +289,8 @@ int main() {
|
|||||||
|
|
||||||
freeActorAPI(&vm);
|
freeActorAPI(&vm);
|
||||||
|
|
||||||
|
// inspect_bucket(&vm.memoryBucket);
|
||||||
|
|
||||||
Toy_freeVM(&vm);
|
Toy_freeVM(&vm);
|
||||||
free(entryCode);
|
free(entryCode);
|
||||||
|
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
//always first member of any opaques
|
//always first member of any opaques
|
||||||
typedef enum OpaqueType {
|
typedef enum OpaqueType {
|
||||||
OPAQUE_KEYBOARD,
|
OPAQUE_KEYBOARD,
|
||||||
|
OPAQUE_KEY_PRESSED,
|
||||||
|
OPAQUE_KEY_RELEASED,
|
||||||
OPAQUE_ACTOR,
|
OPAQUE_ACTOR,
|
||||||
} OpaqueType;
|
} OpaqueType;
|
||||||
|
|
||||||
typedef struct DummyOpaque {
|
|
||||||
OpaqueType type;
|
|
||||||
} DummyOpaque;
|
|
||||||
Reference in New Issue
Block a user