Added keyboard support
This commit is contained in:
+1
-1
Submodule Toy updated: b0387edeb0...bbb1e38649
+46
-4
@@ -1,4 +1,4 @@
|
|||||||
|
//debug testing
|
||||||
var counter = 0;
|
var counter = 0;
|
||||||
var randi: Int = 69420;
|
var randi: Int = 69420;
|
||||||
fn rand() {
|
fn rand() {
|
||||||
@@ -12,6 +12,45 @@ fn wander(actor: Opaque) {
|
|||||||
counter++;
|
counter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: general purpose math functions
|
||||||
|
//TODO: optimize away single-line blocks in the AST
|
||||||
|
|
||||||
|
//player controlled character
|
||||||
|
var playerMaxMotion: Int = 5;
|
||||||
|
var playerMotionX: Int = 0;
|
||||||
|
var playerMotionY: Int = 0;
|
||||||
|
|
||||||
|
fn playerOnFrame(player: Opaque) {
|
||||||
|
//accept input
|
||||||
|
if (Keyboard.UP) {
|
||||||
|
playerMotionY -= 5;
|
||||||
|
}
|
||||||
|
if (Keyboard.DOWN) {
|
||||||
|
playerMotionY += 5;
|
||||||
|
}
|
||||||
|
if (Keyboard.LEFT) {
|
||||||
|
playerMotionX -= 5;
|
||||||
|
}
|
||||||
|
if (Keyboard.RIGHT) {
|
||||||
|
playerMotionX += 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print playerMotionX;
|
||||||
|
// print playerMotionY;
|
||||||
|
// print playerMaxMotion;
|
||||||
|
// print -playerMaxMotion;
|
||||||
|
|
||||||
|
//cap the speed
|
||||||
|
if (playerMotionX > playerMaxMotion) playerMotionX = playerMaxMotion;
|
||||||
|
if (playerMotionX < -playerMaxMotion) playerMotionX = -playerMaxMotion;
|
||||||
|
if (playerMotionY > playerMaxMotion) playerMotionY = playerMaxMotion;
|
||||||
|
if (playerMotionY < -playerMaxMotion) playerMotionY = -playerMaxMotion;
|
||||||
|
|
||||||
|
//move the player
|
||||||
|
player.setX(player.x + playerMotionX);
|
||||||
|
player.setY(player.y + playerMotionY);
|
||||||
|
}
|
||||||
|
|
||||||
//when the game is ready, load the "zombie" sprite
|
//when the game is ready, load the "zombie" sprite
|
||||||
fn onReady() {
|
fn onReady() {
|
||||||
loadSprite("zombie", "assets/parvati.png", 32, 32);
|
loadSprite("zombie", "assets/parvati.png", 32, 32);
|
||||||
@@ -21,14 +60,17 @@ fn onReady() {
|
|||||||
spawnActorAt("zombie", wander, 250, 500);
|
spawnActorAt("zombie", wander, 250, 500);
|
||||||
spawnActorAt("zombie", wander, 500, 250);
|
spawnActorAt("zombie", wander, 500, 250);
|
||||||
spawnActorAt("zombie", wander, 500, 500);
|
spawnActorAt("zombie", wander, 500, 500);
|
||||||
|
|
||||||
|
//spawn the player
|
||||||
|
loadSprite("player", "assets/parvati.png", 32, 32);
|
||||||
|
spawnActorAt("player", playerOnFrame, 300, 300);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn onFrame() {
|
fn onFrame() {
|
||||||
//debug
|
//debug
|
||||||
print counter;
|
// 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, null, null);
|
initLoop(onReady, onFrame, null);
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
#LIBS+=-lm
|
#LIBS+=-lm
|
||||||
#LDFLAGS+=
|
#LDFLAGS+=
|
||||||
|
|
||||||
|
#TODO: add debug & release build options, at least for Toy
|
||||||
|
|
||||||
#directories
|
#directories
|
||||||
export VAMP_SOURCEDIR=source
|
export VAMP_SOURCEDIR=source
|
||||||
export VAMP_OUTDIR=out
|
export VAMP_OUTDIR=out
|
||||||
|
|||||||
+4
-102
@@ -13,7 +13,7 @@
|
|||||||
static Toy_Table* spriteTable = NULL;
|
static Toy_Table* spriteTable = NULL;
|
||||||
static Toy_Array* actorArray = NULL;
|
static Toy_Array* actorArray = NULL;
|
||||||
|
|
||||||
//callbacks
|
//API bindings
|
||||||
static void api_loadSprite(Toy_VM* vm, Toy_FunctionNative* self) {
|
static void api_loadSprite(Toy_VM* vm, Toy_FunctionNative* self) {
|
||||||
//key, file, width, height -> null
|
//key, file, width, height -> null
|
||||||
(void)self;
|
(void)self;
|
||||||
@@ -165,6 +165,7 @@ static void api_spawnActorAt(Toy_VM* vm, Toy_FunctionNative* self) {
|
|||||||
|
|
||||||
//finally, store the new actor's data
|
//finally, store the new actor's data
|
||||||
(*newActorPtr) = (ActorData){
|
(*newActorPtr) = (ActorData){
|
||||||
|
.type = OPAQUE_ACTOR,
|
||||||
.sprite = (SpriteData*)(TOY_VALUE_AS_OPAQUE(spriteValue)),
|
.sprite = (SpriteData*)(TOY_VALUE_AS_OPAQUE(spriteValue)),
|
||||||
.onStep = onStep,
|
.onStep = onStep,
|
||||||
.position = { TOY_VALUE_AS_INTEGER(xpos), TOY_VALUE_AS_INTEGER(ypos) },
|
.position = { TOY_VALUE_AS_INTEGER(xpos), TOY_VALUE_AS_INTEGER(ypos) },
|
||||||
@@ -309,100 +310,7 @@ void drawActors(Toy_VM* vm) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//accessors & mutators
|
//opaque bindings
|
||||||
void loadSprite(Toy_Bucket** bucketHandle, Toy_Value key, const char* fname, int width, int height) {
|
|
||||||
//key, file, width, height -> null
|
|
||||||
|
|
||||||
if (!IsWindowReady()) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't load actor sprites before the window has been initialized" TOY_CC_RESET "\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//check for initialization
|
|
||||||
if (spriteTable == NULL || actorArray == NULL) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Object pool for actor system hasn't been initialized" TOY_CC_RESET "\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//check for overwriting the key
|
|
||||||
if ( TOY_VALUE_IS_NULL(Toy_lookupTable(&spriteTable, key)) != true ) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't overwrite existing actor sprite key" TOY_CC_RESET "\n");
|
|
||||||
Toy_freeValue(key);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
//create the sprite stored in the bucket
|
|
||||||
SpriteData* sprite = (SpriteData*)Toy_partitionBucket(bucketHandle, sizeof(SpriteData));
|
|
||||||
sprite->rect = (Rectangle){ 0, 0, width, height };
|
|
||||||
|
|
||||||
//load the texture from a file
|
|
||||||
sprite->texture = LoadTexture(fname);
|
|
||||||
|
|
||||||
//insert into the table as an opaque
|
|
||||||
Toy_insertTable(&spriteTable, Toy_copyValue(bucketHandle, key), TOY_OPAQUE_FROM_POINTER(sprite));
|
|
||||||
}
|
|
||||||
|
|
||||||
ActorData* spawnActorAt(Toy_Bucket** bucketHandle, Toy_Value key, Toy_Function* onStep, int xpos, int ypos) {
|
|
||||||
//sprite, onStep, x, y -> void
|
|
||||||
|
|
||||||
//check for initialization
|
|
||||||
if (spriteTable == NULL || actorArray == NULL) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Object pool for actor system hasn't been initialized" TOY_CC_RESET "\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//get the sprite
|
|
||||||
Toy_Value spriteValue = Toy_lookupTable(&spriteTable, key);
|
|
||||||
if (TOY_VALUE_IS_NULL(spriteValue)) {
|
|
||||||
Toy_String* string = Toy_stringifyValue(bucketHandle, key);
|
|
||||||
char* cstr = Toy_getStringRaw(string);
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Can't spawn a actor with a non-existant sprite '%s'" TOY_CC_RESET "\n", cstr);
|
|
||||||
free(cstr);
|
|
||||||
Toy_freeString(string);
|
|
||||||
Toy_freeValue(key);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
//expand the array if needed
|
|
||||||
if (actorArray->count == actorArray->capacity) {
|
|
||||||
actorArray = Toy_resizeArray(actorArray, actorArray->capacity * TOY_ARRAY_EXPANSION_RATE);
|
|
||||||
//set the new entries to null values
|
|
||||||
for (unsigned int i = actorArray->count; i < actorArray->capacity; i++) {
|
|
||||||
actorArray->data[i] = TOY_VALUE_FROM_NULL();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//find an existing spot for the new actor, overwriting a dead one if able
|
|
||||||
ActorData* newActorPtr = NULL;
|
|
||||||
for (unsigned int i = 0; i < actorArray->count; i++) {
|
|
||||||
ActorData* mData = (ActorData*)TOY_VALUE_AS_OPAQUE(actorArray->data[i]);
|
|
||||||
if (mData->enabled) { //if this actor is dead, steal the slot
|
|
||||||
newActorPtr = mData;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//if no dead actors were found, make a new slot
|
|
||||||
if (newActorPtr == NULL) {
|
|
||||||
newActorPtr = (ActorData*)Toy_partitionBucket(bucketHandle, sizeof(ActorData));
|
|
||||||
actorArray->data[actorArray->count++] = TOY_OPAQUE_FROM_POINTER(newActorPtr);
|
|
||||||
}
|
|
||||||
|
|
||||||
//finally, store the new actor's data
|
|
||||||
(*newActorPtr) = (ActorData){
|
|
||||||
.sprite = (SpriteData*)(TOY_VALUE_AS_OPAQUE(spriteValue)),
|
|
||||||
.onStep = onStep,
|
|
||||||
.position = { xpos, ypos },
|
|
||||||
.enabled = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
Toy_freeValue(spriteValue);
|
|
||||||
Toy_freeValue(key);
|
|
||||||
|
|
||||||
return newActorPtr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//opaque handler
|
|
||||||
static void attr_actorSetX(Toy_VM* vm, Toy_FunctionNative* self) {
|
static void attr_actorSetX(Toy_VM* vm, Toy_FunctionNative* self) {
|
||||||
(void)self;
|
(void)self;
|
||||||
|
|
||||||
@@ -440,12 +348,6 @@ Toy_Value handleActorAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attrib
|
|||||||
return TOY_VALUE_FROM_NULL();
|
return TOY_VALUE_FROM_NULL();
|
||||||
}
|
}
|
||||||
|
|
||||||
//check for correct types
|
|
||||||
if (!TOY_VALUE_IS_OPAQUE(compound) || !TOY_VALUE_IS_STRING(attribute) || TOY_VALUE_AS_STRING(attribute)->info.type != TOY_STRING_LEAF) {
|
|
||||||
fprintf(stderr, TOY_CC_ERROR "ERROR: Bad parameters found in 'handleActorAttributes'" TOY_CC_RESET "\n");
|
|
||||||
return TOY_VALUE_FROM_NULL(); //do not free the params here
|
|
||||||
}
|
|
||||||
|
|
||||||
ActorData* actor = (ActorData*)TOY_VALUE_AS_OPAQUE(compound);
|
ActorData* actor = (ActorData*)TOY_VALUE_AS_OPAQUE(compound);
|
||||||
|
|
||||||
if (TOY_VALUE_AS_STRING(attribute)->info.length == 1 && strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "x", 1) == 0) {
|
if (TOY_VALUE_AS_STRING(attribute)->info.length == 1 && strncmp(TOY_VALUE_AS_STRING(attribute)->leaf.data, "x", 1) == 0) {
|
||||||
@@ -465,7 +367,7 @@ Toy_Value handleActorAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attrib
|
|||||||
|
|
||||||
else {
|
else {
|
||||||
char buffer[256];
|
char buffer[256];
|
||||||
snprintf(buffer, 256, "Unknown attribute '%s' of type ActorData (an Opaque)", TOY_VALUE_AS_STRING(attribute)->leaf.data);
|
snprintf(buffer, 256, "Unknown attribute '%s' of 'ActorData'", TOY_VALUE_AS_STRING(attribute)->leaf.data);
|
||||||
Toy_error(buffer);
|
Toy_error(buffer);
|
||||||
return TOY_VALUE_FROM_NULL();
|
return TOY_VALUE_FROM_NULL();
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-5
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "opaque_type.h"
|
||||||
#include "toy_vm.h"
|
#include "toy_vm.h"
|
||||||
#include "toy_function.h"
|
#include "toy_function.h"
|
||||||
#include "raylib.h"
|
#include "raylib.h"
|
||||||
@@ -13,21 +14,19 @@ typedef struct SpriteData {
|
|||||||
|
|
||||||
//Actors loaded from scripts
|
//Actors loaded from scripts
|
||||||
typedef struct ActorData {
|
typedef struct ActorData {
|
||||||
|
OpaqueType type;
|
||||||
SpriteData* sprite;
|
SpriteData* sprite;
|
||||||
Toy_Function* onStep;
|
Toy_Function* onStep;
|
||||||
Vector2 position;
|
Vector2 position;
|
||||||
bool enabled;
|
bool enabled;
|
||||||
} ActorData;
|
} ActorData;
|
||||||
|
|
||||||
//object pool system
|
//opaque API
|
||||||
void initActorAPI(Toy_VM* vm);
|
void initActorAPI(Toy_VM* vm);
|
||||||
void freeActorAPI(Toy_VM* vm);
|
void freeActorAPI(Toy_VM* vm);
|
||||||
|
|
||||||
void processActors(Toy_VM* vm);
|
void processActors(Toy_VM* vm);
|
||||||
void drawActors(Toy_VM* vm);
|
void drawActors(Toy_VM* vm);
|
||||||
|
|
||||||
void loadSprite(Toy_Bucket** bucketHandle, Toy_Value key, const char* fname, int width, int height);
|
//opaque binding
|
||||||
ActorData* spawnActorAt(Toy_Bucket** bucketHandle, Toy_Value key, Toy_Function* onStep, int xpos, int ypos);
|
|
||||||
|
|
||||||
//opaque hook
|
|
||||||
Toy_Value handleActorAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute);
|
Toy_Value handleActorAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute);
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
#include "keyboard.h"
|
||||||
|
|
||||||
|
#include "string.h"
|
||||||
|
|
||||||
|
KeyboardMap keyboardMap[] = {
|
||||||
|
{KEY_NULL, ""},
|
||||||
|
{KEY_APOSTROPHE, "APOSTROPHE"},
|
||||||
|
{KEY_COMMA, "COMMA"},
|
||||||
|
{KEY_MINUS, "MINUS"},
|
||||||
|
{KEY_PERIOD, "PERIOD"},
|
||||||
|
{KEY_SLASH, "SLASH"},
|
||||||
|
{KEY_ZERO, "ZERO"},
|
||||||
|
{KEY_ONE, "ONE"},
|
||||||
|
{KEY_TWO, "TWO"},
|
||||||
|
{KEY_THREE, "THREE"},
|
||||||
|
{KEY_FOUR, "FOUR"},
|
||||||
|
{KEY_FIVE, "FIVE"},
|
||||||
|
{KEY_SIX, "SIX"},
|
||||||
|
{KEY_SEVEN, "SEVEN"},
|
||||||
|
{KEY_EIGHT, "EIGHT"},
|
||||||
|
{KEY_NINE, "NINE"},
|
||||||
|
{KEY_SEMICOLON, "SEMICOLON"},
|
||||||
|
{KEY_EQUAL, "EQUAL"},
|
||||||
|
{KEY_A, "A"},
|
||||||
|
{KEY_B, "B"},
|
||||||
|
{KEY_C, "C"},
|
||||||
|
{KEY_D, "D"},
|
||||||
|
{KEY_E, "E"},
|
||||||
|
{KEY_F, "F"},
|
||||||
|
{KEY_G, "G"},
|
||||||
|
{KEY_H, "H"},
|
||||||
|
{KEY_I, "I"},
|
||||||
|
{KEY_J, "J"},
|
||||||
|
{KEY_K, "K"},
|
||||||
|
{KEY_L, "L"},
|
||||||
|
{KEY_M, "M"},
|
||||||
|
{KEY_N, "N"},
|
||||||
|
{KEY_O, "O"},
|
||||||
|
{KEY_P, "P"},
|
||||||
|
{KEY_Q, "Q"},
|
||||||
|
{KEY_R, "R"},
|
||||||
|
{KEY_S, "S"},
|
||||||
|
{KEY_T, "T"},
|
||||||
|
{KEY_U, "U"},
|
||||||
|
{KEY_V, "V"},
|
||||||
|
{KEY_W, "W"},
|
||||||
|
{KEY_X, "X"},
|
||||||
|
{KEY_Y, "Y"},
|
||||||
|
{KEY_Z, "Z"},
|
||||||
|
{KEY_LEFT_BRACKET, "LEFT_BRACKET"},
|
||||||
|
{KEY_BACKSLASH, "BACKSLASH"},
|
||||||
|
{KEY_RIGHT_BRACKET, "RIGHT_BRACKET"},
|
||||||
|
{KEY_GRAVE, "GRAVE"},
|
||||||
|
{KEY_SPACE, "SPACE"},
|
||||||
|
{KEY_ESCAPE, "ESCAPE"},
|
||||||
|
{KEY_ENTER, "ENTER"},
|
||||||
|
{KEY_TAB, "TAB"},
|
||||||
|
{KEY_BACKSPACE, "BACKSPACE"},
|
||||||
|
{KEY_INSERT, "INSERT"},
|
||||||
|
{KEY_DELETE, "DELETE"},
|
||||||
|
{KEY_RIGHT, "RIGHT"},
|
||||||
|
{KEY_LEFT, "LEFT"},
|
||||||
|
{KEY_DOWN, "DOWN"},
|
||||||
|
{KEY_UP, "UP"},
|
||||||
|
{KEY_PAGE_UP, "PAGE_UP"},
|
||||||
|
{KEY_PAGE_DOWN, "PAGE_DOWN"},
|
||||||
|
{KEY_HOME, "HOME"},
|
||||||
|
{KEY_END, "END"},
|
||||||
|
{KEY_CAPS_LOCK, "CAPS_LOCK"},
|
||||||
|
{KEY_SCROLL_LOCK, "SCROLL_LOCK"},
|
||||||
|
{KEY_NUM_LOCK, "NUM_LOCK"},
|
||||||
|
{KEY_PRINT_SCREEN, "PRINT_SCREEN"},
|
||||||
|
{KEY_PAUSE, "PAUSE"},
|
||||||
|
{KEY_F1, "F1"},
|
||||||
|
{KEY_F2, "F2"},
|
||||||
|
{KEY_F3, "F3"},
|
||||||
|
{KEY_F4, "F4"},
|
||||||
|
{KEY_F5, "F5"},
|
||||||
|
{KEY_F6, "F6"},
|
||||||
|
{KEY_F7, "F7"},
|
||||||
|
{KEY_F8, "F8"},
|
||||||
|
{KEY_F9, "F9"},
|
||||||
|
{KEY_F10, "F10"},
|
||||||
|
{KEY_F11, "F11"},
|
||||||
|
{KEY_F12, "F12"},
|
||||||
|
{KEY_LEFT_SHIFT, "LEFT_SHIFT"},
|
||||||
|
{KEY_LEFT_CONTROL, "LEFT_CONTROL"},
|
||||||
|
{KEY_LEFT_ALT, "LEFT_ALT"},
|
||||||
|
{KEY_LEFT_SUPER, "LEFT_SUPER"},
|
||||||
|
{KEY_RIGHT_SHIFT, "RIGHT_SHIFT"},
|
||||||
|
{KEY_RIGHT_CONTROL, "RIGHT_CONTROL"},
|
||||||
|
{KEY_RIGHT_ALT, "RIGHT_ALT"},
|
||||||
|
{KEY_RIGHT_SUPER, "RIGHT_SUPER"},
|
||||||
|
{KEY_KB_MENU, "KB_MENU"},
|
||||||
|
{KEY_KP_0, "KP_0"},
|
||||||
|
{KEY_KP_1, "KP_1"},
|
||||||
|
{KEY_KP_2, "KP_2"},
|
||||||
|
{KEY_KP_3, "KP_3"},
|
||||||
|
{KEY_KP_4, "KP_4"},
|
||||||
|
{KEY_KP_5, "KP_5"},
|
||||||
|
{KEY_KP_6, "KP_6"},
|
||||||
|
{KEY_KP_7, "KP_7"},
|
||||||
|
{KEY_KP_8, "KP_8"},
|
||||||
|
{KEY_KP_9, "KP_9"},
|
||||||
|
{KEY_KP_DECIMAL, "KP_DECIMAL"},
|
||||||
|
{KEY_KP_DIVIDE, "KP_DIVIDE"},
|
||||||
|
{KEY_KP_MULTIPLY, "KP_MULTIPLY"},
|
||||||
|
{KEY_KP_SUBTRACT, "KP_SUBTRACT"},
|
||||||
|
{KEY_KP_ADD, "KP_ADD"},
|
||||||
|
{KEY_KP_ENTER, "KP_ENTER"},
|
||||||
|
{KEY_KP_EQUAL, "KP_EQUAL"},
|
||||||
|
{KEY_BACK, "BACK"},
|
||||||
|
{KEY_MENU, "MENU"},
|
||||||
|
{KEY_VOLUME_UP, "VOLUME_UP"},
|
||||||
|
{KEY_VOLUME_DOWN, "VOLUME_DOWN"},
|
||||||
|
{0, NULL},
|
||||||
|
};
|
||||||
|
|
||||||
|
KeyboardData keyboardData = { //NOTE: it is just a dummy struct right now so the API looks nice
|
||||||
|
.type = OPAQUE_KEYBOARD,
|
||||||
|
};
|
||||||
|
|
||||||
|
Toy_Value handleKeyboardAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
||||||
|
(void)vm;
|
||||||
|
(void)compound;
|
||||||
|
|
||||||
|
Toy_String* string = TOY_VALUE_AS_STRING(attribute);
|
||||||
|
const char* cstr = string->leaf.data;
|
||||||
|
|
||||||
|
//find the mapped value, if available
|
||||||
|
for (KeyboardMap* ptr = keyboardMap; ptr->cstr != NULL; ptr++) {
|
||||||
|
if (strlen(ptr->cstr) == strlen(cstr) && strncmp(cstr, ptr->cstr, strlen(ptr->cstr)) == 0) {
|
||||||
|
bool result = IsKeyPressed(ptr->raykey);
|
||||||
|
return TOY_VALUE_FROM_BOOLEAN(result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//unknown key
|
||||||
|
return TOY_VALUE_FROM_NULL();
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "opaque_type.h"
|
||||||
|
#include "toy_vm.h"
|
||||||
|
#include "raylib.h"
|
||||||
|
|
||||||
|
//wraps raylib's 'KeyboardKey' enum to a c-string
|
||||||
|
typedef struct KeyboardMap {
|
||||||
|
int raykey;
|
||||||
|
char* cstr;
|
||||||
|
} KeyboardMap;
|
||||||
|
|
||||||
|
extern KeyboardMap keyboardMap[];
|
||||||
|
|
||||||
|
//keyboard opaque
|
||||||
|
typedef struct KeyboardData {
|
||||||
|
OpaqueType type;
|
||||||
|
} KeyboardData;
|
||||||
|
|
||||||
|
extern KeyboardData keyboardData;
|
||||||
|
|
||||||
|
Toy_Value handleKeyboardAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute);
|
||||||
+37
-9
@@ -8,12 +8,15 @@
|
|||||||
#include "toy_vm.h"
|
#include "toy_vm.h"
|
||||||
#include "toy_attributes.h"
|
#include "toy_attributes.h"
|
||||||
|
|
||||||
|
#include "keyboard.h"
|
||||||
#include "actor.h"
|
#include "actor.h"
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
// #include "bytecode_inspector.h"
|
||||||
|
|
||||||
//utils
|
//utils
|
||||||
unsigned char* readFile(char* path, int* size) {
|
unsigned char* readFile(char* path, int* size) {
|
||||||
//open the file
|
//open the file
|
||||||
@@ -43,7 +46,7 @@ unsigned char* readFile(char* path, int* size) {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer[(*size)++] = '\0';
|
buffer[(*size)] = '\0';
|
||||||
|
|
||||||
//clean up and return
|
//clean up and return
|
||||||
fclose(file);
|
fclose(file);
|
||||||
@@ -144,7 +147,31 @@ void api_initLoop(Toy_VM* vm, Toy_FunctionNative* self) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//game API tools
|
//opaque dispatch
|
||||||
|
Toy_Value dispatchOpaqueAttributes(Toy_VM* vm, Toy_Value compound, Toy_Value attribute) {
|
||||||
|
//check for correct types
|
||||||
|
if (!TOY_VALUE_IS_OPAQUE(compound) || !TOY_VALUE_IS_STRING(attribute) || TOY_VALUE_AS_STRING(attribute)->info.type != TOY_STRING_LEAF) {
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "ERROR: Bad parameters found in 'handleOpaqueAttributes'" TOY_CC_RESET "\n");
|
||||||
|
return TOY_VALUE_FROM_NULL(); //do not free the params here
|
||||||
|
}
|
||||||
|
|
||||||
|
//assume the first byte is the type
|
||||||
|
OpaqueType* type = (OpaqueType*)TOY_VALUE_AS_OPAQUE(compound);
|
||||||
|
|
||||||
|
switch(*type) {
|
||||||
|
case OPAQUE_KEYBOARD:
|
||||||
|
return handleKeyboardAttributes(vm, compound, attribute);
|
||||||
|
|
||||||
|
case OPAQUE_ACTOR:
|
||||||
|
return handleActorAttributes(vm, compound, attribute);
|
||||||
|
|
||||||
|
default:
|
||||||
|
fprintf(stderr, TOY_CC_ERROR "ERROR: Bad opaque type found in 'handleOpaqueAttributes'" TOY_CC_RESET "\n");
|
||||||
|
return TOY_VALUE_FROM_NULL(); //do not free the params here
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//API tools
|
||||||
typedef struct CallbackPairs {
|
typedef struct CallbackPairs {
|
||||||
const char* name;
|
const char* name;
|
||||||
Toy_nativeCallback callback;
|
Toy_nativeCallback callback;
|
||||||
@@ -169,6 +196,11 @@ void initGameAPI(Toy_VM* vm) {
|
|||||||
Toy_declareScope(vm->scope, key, TOY_VALUE_FUNCTION, TOY_VALUE_FROM_FUNCTION(fn), true);
|
Toy_declareScope(vm->scope, key, TOY_VALUE_FUNCTION, TOY_VALUE_FROM_FUNCTION(fn), true);
|
||||||
Toy_freeString(key);
|
Toy_freeString(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//declare keyboard opaque
|
||||||
|
Toy_String* keyboardString = Toy_toString(&vm->memoryBucket, "Keyboard");
|
||||||
|
Toy_declareScope(vm->scope, keyboardString, TOY_VALUE_OPAQUE, TOY_OPAQUE_FROM_POINTER(&keyboardData), true);
|
||||||
|
Toy_freeString(keyboardString);
|
||||||
}
|
}
|
||||||
|
|
||||||
//main file
|
//main file
|
||||||
@@ -191,7 +223,9 @@ int main() {
|
|||||||
|
|
||||||
initGameAPI(&vm);
|
initGameAPI(&vm);
|
||||||
initActorAPI(&vm);
|
initActorAPI(&vm);
|
||||||
Toy_setOpaqueAttributeHandler(handleActorAttributes);
|
Toy_setOpaqueAttributeHandler(dispatchOpaqueAttributes);
|
||||||
|
|
||||||
|
// inspect_bytecode(entryCode);
|
||||||
|
|
||||||
Toy_runVM(&vm);
|
Toy_runVM(&vm);
|
||||||
Toy_resetVM(&vm, false, false); //leave in a valid, but unset state
|
Toy_resetVM(&vm, false, false); //leave in a valid, but unset state
|
||||||
@@ -209,12 +243,6 @@ int main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (!WindowShouldClose()) {
|
while (!WindowShouldClose()) {
|
||||||
//TODO: player input
|
|
||||||
// if (IsKeyDown(KEY_UP)) player.position.y -= 5.0f;
|
|
||||||
// if (IsKeyDown(KEY_DOWN)) player.position.y += 5.0f;
|
|
||||||
// if (IsKeyDown(KEY_LEFT)) player.position.x -= 5.0f;
|
|
||||||
// if (IsKeyDown(KEY_RIGHT)) player.position.x += 5.0f;
|
|
||||||
|
|
||||||
//process the actors (if possible)
|
//process the actors (if possible)
|
||||||
processActors(&vm);
|
processActors(&vm);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
//always first member of any opaques
|
||||||
|
typedef enum OpaqueType {
|
||||||
|
OPAQUE_KEYBOARD,
|
||||||
|
OPAQUE_ACTOR,
|
||||||
|
} OpaqueType;
|
||||||
|
|
||||||
|
typedef struct DummyOpaque {
|
||||||
|
OpaqueType type;
|
||||||
|
} DummyOpaque;
|
||||||
Reference in New Issue
Block a user