Added two folders: test/ and xibalba/. Contained within test/ are two test/devel-beds for two systems that will be integrated within ts. The first is script.c, which is the development program for the interpreter system - this interpreter system allows for the setting of variables (both local and global), the creation of new functions, and the definition of default in-game functions such as dice rolling and the like. The second file, t2d.c functions as a basic test utility for Tile Data loading and the like - it interprets a tileset/tile definition file into Data, TileDataSet, and TileData(s) respectively. These structs, as defined in data.c/.h, allow for reference to tiles by TID:ID or simply by name through the use of key=>value pairs. It is from these structs and their accompanying access functions that new Tiles will be created (perhaps later optimized through a basic Tile array that contains semi-populated Tile(s) that can be memcpy'd similar to the current system). Also added the xibalba/ sub-dir that will contain the various data for Xibalba (tile definitions, graphics, map creation, etc.), moving majority of what is in tiles/ into xibalba/.
parent
b3a3831cd2
commit
e2e015c76b
8
Makefile
8
Makefile
|
@ -1,7 +1,7 @@
|
|||
CC = gcc
|
||||
PREFIX = ./
|
||||
BINARY=timesynk
|
||||
OBJS = main.o game.o parser.o context.o player.o inventory.o npc.o message.o console.o tile.o map.o wall.o net/sockets.o helper.o
|
||||
OBJS = main.o game.o parser.o context.o player.o inventory.o npc.o message.o console.o tile.o map.o wall.o net/sockets.o helper.o data.o
|
||||
CURSES_OBJS = interface/curses.o tiles/curses_tiles.o
|
||||
SDL_OBJS = interface/sdl.o tiles/tiles.o
|
||||
DEBUG = -g
|
||||
|
@ -37,6 +37,7 @@ all: $(BINARY)
|
|||
clean:
|
||||
rm -f $(OBJS) tiles.o $(CURSES_OBJS) $(SDL_OBJS) $(BINARY)
|
||||
rm -f pack_tiles
|
||||
cd test && make clean
|
||||
|
||||
pack_tiles: pack_tiles.c
|
||||
$(CC) pack_tiles.c -o pack_tiles
|
||||
|
@ -63,9 +64,12 @@ map.o: map.h map.c tile.h
|
|||
wall.o: wall.h wall.c
|
||||
$(CC) $(CFLAGS) -c wall.c
|
||||
|
||||
game.o: game.h game.c
|
||||
game.o: game.h game.c data.h
|
||||
$(CC) $(CFLAGS) -c game.c
|
||||
|
||||
data.o: data.h data.c
|
||||
$(CC) $(CFLAGS) -c data.c
|
||||
|
||||
parser.o: parser.h parser.c
|
||||
$(CC) $(CFLAGS) -c parser.c
|
||||
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
/****** data.c
|
||||
This file contains the functions for loading Data, be they Tiles or otherwise, from text data into TileData/TileSetData/Data structures. Additionally are defined functions for populating TileData into *Tile structures (as would be used from map generation or spawning operations).
|
||||
******/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "data.h"
|
||||
/**** loadDataFromMemory
|
||||
Loads given data from memory into a Data struct, also populating TileSetData and TileData structs.
|
||||
|
||||
****/
|
||||
struct Data *loadDataFromMemory(char *memory, int size) {
|
||||
struct Data *data = malloc(sizeof(struct Data));
|
||||
data->size = SET_SIZE;
|
||||
data->id = malloc(sizeof(int)*SET_SIZE);
|
||||
data->set = malloc(sizeof(struct TileSetData*)*SET_SIZE);
|
||||
memset(data->set, 0, sizeof(struct TileSetData*)*SET_SIZE);
|
||||
int offset = 0;
|
||||
int depth = 0; // used to manage position!
|
||||
data->set_count = 0;
|
||||
while (offset <= size) {
|
||||
if (memory[offset] == '{') {
|
||||
depth++;
|
||||
offset++; // skip that bracket
|
||||
if (depth == 1) {
|
||||
// now we get our tileset's id
|
||||
char temp_string[31];
|
||||
int temp_offset = offset-1;
|
||||
int temp_offset_2 = 0;
|
||||
while (memory[temp_offset] != '\n' && temp_offset > 0) {
|
||||
temp_offset--;
|
||||
}
|
||||
while (memory[temp_offset] != '{') {
|
||||
temp_string[temp_offset_2++] = memory[temp_offset++];
|
||||
}
|
||||
temp_string[temp_offset_2] = '\0';
|
||||
|
||||
int tileset_id = atoi(temp_string);
|
||||
// resize Data if tileset's id is greater than our size
|
||||
if (tileset_id > data->size) {
|
||||
data->size += tileset_id-data->size;
|
||||
void *ret;
|
||||
ret = realloc(data->id, sizeof(int)*data->size);
|
||||
ret = realloc(data->set, sizeof(struct TileSetData*)*data->size);
|
||||
}
|
||||
data->set[tileset_id] = loadTileSetData(memory, &offset, &depth);
|
||||
data->set_count++;
|
||||
}
|
||||
} else if (memory[offset] == '}') {
|
||||
depth--;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
struct TileSetData *loadTileSetData(char *memory, int *offset, int *depth) {
|
||||
struct TileSetData *set_data = malloc(sizeof(struct TileSetData));
|
||||
set_data->size = SET_SIZE; // default of 32
|
||||
set_data->id = malloc(sizeof(int)*SET_SIZE);
|
||||
set_data->tile = malloc(sizeof(struct TileData*)*SET_SIZE);
|
||||
/* populate Tiles! */
|
||||
while (*depth != 0) {
|
||||
if (memory[*offset] == '{') {
|
||||
*offset = *offset + 1; //skip the bracket
|
||||
*depth = *depth + 1;
|
||||
if (*depth == 2) {
|
||||
// now we get our tileset's id
|
||||
char temp_string[31];
|
||||
int temp_offset = *offset-1;
|
||||
int temp_offset_2 = 0;
|
||||
while (memory[temp_offset] != '\n' && temp_offset > 0) {
|
||||
temp_offset--;
|
||||
}
|
||||
while (memory[temp_offset] != '{') {
|
||||
temp_string[temp_offset_2++] = memory[temp_offset++];
|
||||
}
|
||||
temp_string[temp_offset_2] = '\0';
|
||||
|
||||
int tile_id = atoi(temp_string);
|
||||
// resize Data if tileset's id is greater than our size
|
||||
if (tile_id > set_data->size) {
|
||||
set_data->size += tile_id-set_data->size;
|
||||
void *ret;
|
||||
ret = realloc(set_data->id, sizeof(int)*set_data->size);
|
||||
ret = realloc(set_data->tile, sizeof(struct TileData*)*set_data->size);
|
||||
}
|
||||
set_data->tile[tile_id] = loadTileData(memory, offset, depth);
|
||||
set_data->tile_count++;
|
||||
}
|
||||
|
||||
} else if (memory[*offset] == '}') {
|
||||
*depth = *depth - 1;
|
||||
}
|
||||
*offset = *offset + 1;
|
||||
}
|
||||
return set_data;
|
||||
}
|
||||
|
||||
struct TileData *loadTileData(char *memory, int *offset, int *depth) {
|
||||
struct TileData *tile_data = malloc(sizeof(struct TileData));
|
||||
tile_data->count = 0;
|
||||
tile_data->length = 8;
|
||||
tile_data->keys = malloc(sizeof(char*)*8);
|
||||
tile_data->size = malloc(sizeof(char*)*8);
|
||||
tile_data->values = malloc(sizeof(void*)*8);
|
||||
|
||||
char var_name[32]; // max 32 chars for var name
|
||||
char var_value[256]; // max 256 chars for value
|
||||
|
||||
int i = 0;
|
||||
|
||||
short mode = 0;
|
||||
while(*depth > 1) {
|
||||
switch (memory[*offset]) {
|
||||
case '{':
|
||||
*depth = *depth + 1;
|
||||
break;
|
||||
case '}':
|
||||
*depth = *depth - 1;
|
||||
break;
|
||||
case ' ':
|
||||
if (mode == 1) {
|
||||
var_name[i] = '\0';
|
||||
i = 0;
|
||||
mode = 2;
|
||||
} else if (mode == 2) {
|
||||
var_value[i++] = memory[*offset];
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
var_value[i] = '\0';
|
||||
if (mode == 2) {
|
||||
// generate key=>value pairs and parse value into types (string, int, float)
|
||||
printf("%s=>%s\n", var_name, var_value);
|
||||
}
|
||||
i = 0;
|
||||
mode = 0;
|
||||
break;
|
||||
default:
|
||||
if (mode == 1) {
|
||||
var_name[i++] = memory[*offset];
|
||||
} else if (mode == 2) {
|
||||
var_value[i++] = memory[*offset];
|
||||
} else if (mode == 0) {
|
||||
mode = 1;
|
||||
var_name[i++] = memory[*offset];
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (*depth <= 1)
|
||||
break;
|
||||
*offset = *offset + 1;
|
||||
}
|
||||
return tile_data;
|
||||
}
|
||||
|
||||
int setTileDataSize(struct TileData *tile_data, int size) {
|
||||
tile_data->length = size;
|
||||
void *ret;
|
||||
ret = realloc(tile_data->keys, sizeof(char*)*size);
|
||||
if (ret == NULL)
|
||||
return 1;
|
||||
ret = realloc(tile_data->size, sizeof(char*)*size);
|
||||
if (ret == NULL)
|
||||
return 2;
|
||||
ret = realloc(tile_data->values, sizeof(void*)*size);
|
||||
if (ret == NULL)
|
||||
return 3;
|
||||
if (tile_data->count > size)
|
||||
tile_data->count = size;
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef DATA_H
|
||||
#define DATA_H
|
||||
|
||||
#define SET_SIZE 32 // base set size of 32, if tiles go beyond, the set is realloc'd with this amount
|
||||
|
||||
struct Data {
|
||||
int set_count;
|
||||
int size;
|
||||
int *id; // 0 = player, 1 = npc, etc.
|
||||
struct TileSetData **set;
|
||||
};
|
||||
|
||||
struct TileSetData {
|
||||
char **keys; // ties to tiles entry
|
||||
int *key_id; // key_id acquired from key hash that points to tiles[id], allows for acquiring TileData from a string key as well as an id.
|
||||
int size;
|
||||
int tile_count;
|
||||
int *id;
|
||||
struct TileData **tile;
|
||||
};
|
||||
|
||||
struct TileData {
|
||||
int count; // count of key=>value pairs
|
||||
int length; // max amount of entries
|
||||
char **keys; // i.e., "name"
|
||||
char **size; // since we're void, we should keep track of entry lengths
|
||||
void **values; // i..e, "nupi"
|
||||
};
|
||||
|
||||
struct Data *loadDataFromMemory(char *memory, int size);
|
||||
struct TileSetData *loadTileSetData(char *memory, int *offset, int *depth);
|
||||
struct TileData *loadTileData(char *memory, int *offset, int *depth);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,20 @@
|
|||
CC = gcc
|
||||
CFLAGS = -Wall -c -g
|
||||
|
||||
t2d: t2d.o data.o
|
||||
$(CC) t2d.o data.o -o t2d
|
||||
|
||||
script: script.o
|
||||
$(CC) script.o -o script
|
||||
|
||||
script.o: script.c
|
||||
$(CC) $(CFLAGS) -c script.c
|
||||
|
||||
data.o: ../data.h ../data.c
|
||||
$(CC) $(CFLAGS) -c ../data.c
|
||||
|
||||
t2d.o: t2d.c
|
||||
$(CC) $(CFLAGS) -c t2d.c
|
||||
|
||||
clean:
|
||||
rm -f t2d script *.o
|
|
@ -0,0 +1,634 @@
|
|||
/****** script.c
|
||||
This is the test/devel environment for the ts interpreter/scripting language. It provides a basic CLI for entering script to be interpreted live.
|
||||
******/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h> // ULONG_MAX
|
||||
|
||||
#define DIGIT 1
|
||||
#define ALPHA 2
|
||||
|
||||
#define VAR_SET 1
|
||||
#define RETURN 2
|
||||
|
||||
//#define TEST_FUNC "var1 = 2;\nvar2 = 4;\ndam = 2 * 2 / 2;\n.dam;\n"
|
||||
//#define TEST_FUNC "var1 = 8;\ndam = var1 * 2 / 4;\n.dam;\n"
|
||||
//#define TEST_FUNC "var1 = 2;var2 = 3;var3 = 7;dam = var1 * var2 * var3;dam = dam * var2;.dam;"
|
||||
#define TEST_FUNC "var1 = 2;var2 = 3;var3 = 7;var4 = 22;dam = var1 * var2 * var4 / var3;dam = dam * var2;.dam;"
|
||||
#define TEST_FULL_FUNC "test { var1 = 2;var2 = 3;var3 = 7;dam = var1 * var2 * var3;dam = dam * var2;.dam; }"
|
||||
#define TEST_FUNC_CALL "fcall { var = test();.var; }"
|
||||
#define ROLL_FUNC "roll { var=_roll($_1,$_2);.var; }"
|
||||
|
||||
struct Arguments {
|
||||
const char *arg1;
|
||||
const char *arg2;
|
||||
const char *arg3;
|
||||
const char *arg4;
|
||||
};
|
||||
|
||||
typedef char *(*fptr)(char*);
|
||||
|
||||
struct FuncTable {
|
||||
int size;
|
||||
char **keys;
|
||||
//void (**func)();
|
||||
fptr *func;
|
||||
};
|
||||
|
||||
struct FuncTable *newFuncTable(int size) {
|
||||
struct FuncTable *func_table = malloc(sizeof(struct FuncTable));
|
||||
func_table->size = size;
|
||||
func_table->keys = malloc(sizeof(char*)*size);
|
||||
//func_table->func = malloc(sizeof(void*)*size);
|
||||
func_table->func = malloc(sizeof(fptr*)*size);
|
||||
return func_table;
|
||||
}
|
||||
|
||||
void freeFuncTable(struct FuncTable *func_table) {
|
||||
free(func_table->keys);
|
||||
free(func_table->func);
|
||||
free(func_table);
|
||||
}
|
||||
|
||||
int getFuncIndex(struct FuncTable *func_table, char *key) {
|
||||
unsigned long int func = 0;
|
||||
int i = 0;
|
||||
while (func < ULONG_MAX && i < strlen(key)) {
|
||||
func += key[i++];
|
||||
}
|
||||
return func % func_table->size;
|
||||
}
|
||||
|
||||
void addFunc(struct FuncTable *func_table, char *key, void(*func)) {
|
||||
int index = getFuncIndex(func_table, key);
|
||||
func_table->keys[index] = key;
|
||||
func_table->func[index] = func;
|
||||
}
|
||||
|
||||
fptr runFunc(struct FuncTable *func_table, char *key) {
|
||||
return func_table->func[getFuncIndex(func_table, key)];
|
||||
}
|
||||
|
||||
struct HashTable {
|
||||
int size;
|
||||
char **keys;
|
||||
void **values;
|
||||
};
|
||||
|
||||
struct FuncTable *g_functions;
|
||||
|
||||
struct HashTable *newHashTable(int size) {
|
||||
struct HashTable *hash_table = malloc(sizeof(struct HashTable));
|
||||
hash_table->size = size;
|
||||
hash_table->keys = malloc(sizeof(char*)*size);
|
||||
hash_table->values = malloc(sizeof(void*)*size);
|
||||
return hash_table;
|
||||
}
|
||||
|
||||
void freeHashTable(struct HashTable *hash_table) {
|
||||
free(hash_table->keys);
|
||||
free(hash_table->values);
|
||||
free(hash_table);
|
||||
}
|
||||
|
||||
int getHashIndex(struct HashTable *hash_table, char *key) {
|
||||
unsigned long int hash = 0;
|
||||
int i = 0;
|
||||
while (hash < ULONG_MAX && i < strlen(key)) {
|
||||
hash += key[i++];
|
||||
}
|
||||
return hash % hash_table->size;
|
||||
}
|
||||
|
||||
void addHash(struct HashTable *hash_table, char *key, void *value) {
|
||||
int index = getHashIndex(hash_table, key);
|
||||
hash_table->keys[index] = key;
|
||||
hash_table->values[index] = value;
|
||||
}
|
||||
|
||||
void *getHash(struct HashTable *hash_table, char *key) {
|
||||
return hash_table->values[getHashIndex(hash_table, key)];
|
||||
}
|
||||
|
||||
struct VarTable {
|
||||
int size;
|
||||
char **keys;
|
||||
char **values;
|
||||
};
|
||||
struct VarTable *function_table;
|
||||
|
||||
char *parseAndCallFunction(struct VarTable *var_table, const char *buffer);
|
||||
|
||||
struct VarTable *newVarTable(int size) {
|
||||
struct VarTable *var_table = malloc(sizeof(struct VarTable));
|
||||
var_table->size = size;
|
||||
var_table->keys = malloc(sizeof(char*)*size);
|
||||
var_table->values = malloc(sizeof(char*)*size);
|
||||
return var_table;
|
||||
}
|
||||
|
||||
void freeVarTable(struct VarTable *var_table) {
|
||||
// TODO: free key-value pairs
|
||||
free(var_table->keys);
|
||||
free(var_table->values);
|
||||
free(var_table);
|
||||
}
|
||||
|
||||
int getVarIndex(struct VarTable *var_table, const char *key) {
|
||||
// int hash = 0;
|
||||
unsigned long int hash = 0;
|
||||
int i = 0;
|
||||
while (hash < ULONG_MAX && i < strlen(key)) {
|
||||
//while (i < strlen(key)) {
|
||||
//hash = hash << 8;
|
||||
hash += key[i++];
|
||||
}
|
||||
return hash % var_table->size;
|
||||
}
|
||||
|
||||
void addVar(struct VarTable *var_table, const char *key, char *value) {
|
||||
int index = getVarIndex(var_table, key);
|
||||
int key_length = strlen(key)+1;
|
||||
var_table->keys[index] = malloc(key_length);
|
||||
memcpy(var_table->keys[index], key, key_length);
|
||||
int value_length = strlen(value)+1;
|
||||
var_table->values[index] = malloc(value_length);
|
||||
memcpy(var_table->values[index], value, value_length);
|
||||
}
|
||||
|
||||
void freeVar(struct VarTable *var_table, const char *key) {
|
||||
int index = getVarIndex(var_table, key);
|
||||
if (var_table->keys[index])
|
||||
free(var_table->keys[index]);
|
||||
if (var_table->values[index])
|
||||
free(var_table->values[index]);
|
||||
}
|
||||
|
||||
char *getVar(struct VarTable *var_table, const char *key) {
|
||||
int index = getVarIndex(var_table, key);
|
||||
return var_table->values[index];
|
||||
}
|
||||
|
||||
struct Var {
|
||||
int bytes;
|
||||
char type;
|
||||
char operation;
|
||||
char *data;
|
||||
};
|
||||
|
||||
char* itoa(int value, char* result, int base) {
|
||||
// check that the base if valid
|
||||
if (base < 2 || base > 36) { *result = '\0'; return result; }
|
||||
|
||||
char* ptr = result, *ptr1 = result, tmp_char;
|
||||
int tmp_value;
|
||||
|
||||
do {
|
||||
tmp_value = value;
|
||||
value /= base;
|
||||
*ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz" [35 + (tmp_value - value * base)];
|
||||
} while ( value );
|
||||
|
||||
// Apply negative sign
|
||||
if (tmp_value < 0) *ptr++ = '-';
|
||||
*ptr-- = '\0';
|
||||
while(ptr1 < ptr) {
|
||||
tmp_char = *ptr;
|
||||
*ptr--= *ptr1;
|
||||
*ptr1++ = tmp_char;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// TODO: replace Arguments with v_printf stuff
|
||||
void doOperation(struct VarTable *var_table, const char **args, int arg_count, char *return_string, const char *string) {
|
||||
printf("args: %d\n", arg_count);
|
||||
//printf("operation is %s\n", string);
|
||||
int s_i = 0; // string iterator
|
||||
int b_i = 0; // buffer iterator
|
||||
int bt_i = 0; // buffer type iterator
|
||||
char buffer[255]; // buffer that holds the portion being processed
|
||||
|
||||
struct Var vars[31]; // max 31 variables
|
||||
int var_i = 0;
|
||||
int c_i = 0; // current var iterator
|
||||
|
||||
char *f_return; // function call pointer
|
||||
|
||||
while (string[s_i] != '\0') {
|
||||
switch (string[s_i]) {
|
||||
case '+':
|
||||
case '-':
|
||||
case '/':
|
||||
case '*':
|
||||
if (isdigit(buffer[0]))
|
||||
vars[var_i].type = DIGIT;
|
||||
else
|
||||
vars[var_i].type = ALPHA;
|
||||
buffer[b_i] = '\0';
|
||||
if (vars[var_i].type == ALPHA) {
|
||||
if (arg_count > 0)
|
||||
printf("first part of arg0: %c\n", args[0][0]);
|
||||
if (buffer[b_i-1] == ')') {
|
||||
f_return = parseAndCallFunction(var_table, buffer);
|
||||
vars[var_i].bytes = strlen(f_return)+1;
|
||||
vars[var_i].data = malloc(vars[var_i].bytes);
|
||||
strcpy(vars[var_i].data, f_return);
|
||||
free(f_return);
|
||||
} else {
|
||||
vars[var_i].bytes = strlen(getVar(var_table, buffer))+1;
|
||||
vars[var_i].data = malloc(vars[var_i].bytes);
|
||||
strcpy(vars[var_i].data, getVar(var_table, buffer));
|
||||
}
|
||||
} else {
|
||||
vars[var_i].bytes = strlen(buffer)+1;
|
||||
vars[var_i].data = malloc(vars[var_i].bytes);
|
||||
strcpy(vars[var_i].data, buffer);
|
||||
}
|
||||
memset(&buffer, '\0', 255);
|
||||
b_i = 0;
|
||||
vars[var_i].operation = string[s_i];
|
||||
var_i++;
|
||||
break;
|
||||
case ';':
|
||||
buffer[b_i] = '\0';
|
||||
// determine variable type
|
||||
if (isdigit(buffer[0]))
|
||||
vars[var_i].type = DIGIT;
|
||||
else
|
||||
vars[var_i].type = ALPHA;
|
||||
if (vars[var_i].type == ALPHA) {
|
||||
if (buffer[b_i-1] == ')') {
|
||||
f_return = parseAndCallFunction(var_table, buffer);
|
||||
vars[var_i].bytes = strlen(f_return)+1;
|
||||
vars[var_i].data = malloc(vars[var_i].bytes);
|
||||
strcpy(vars[var_i].data, f_return);
|
||||
free(f_return);
|
||||
} else {
|
||||
vars[var_i].bytes = strlen(getVar(var_table, buffer))+1;
|
||||
vars[var_i].data = malloc(vars[var_i].bytes);
|
||||
strcpy(vars[var_i].data, getVar(var_table, buffer));
|
||||
}
|
||||
} else {
|
||||
vars[var_i].bytes = strlen(buffer)+1;
|
||||
vars[var_i].data = malloc(vars[var_i].bytes);
|
||||
strcpy(vars[var_i].data, buffer);
|
||||
}
|
||||
// "clear" buffer
|
||||
memset(&buffer, '\0', 255);
|
||||
b_i = 0;
|
||||
// ALRIGHT, now let's do the operaton
|
||||
c_i = 0;
|
||||
while (c_i < var_i) {
|
||||
switch (vars[c_i].operation) {
|
||||
case '+':
|
||||
itoa(atoi(vars[c_i].data) + atoi(vars[c_i+1].data), vars[c_i+1].data, 10);
|
||||
break;
|
||||
case '-':
|
||||
itoa(atoi(vars[c_i].data) - atoi(vars[c_i+1].data), vars[c_i+1].data, 10);
|
||||
break;
|
||||
case '*':
|
||||
itoa(atoi(vars[c_i].data) * atoi(vars[c_i+1].data), vars[c_i+1].data, 10);
|
||||
break;
|
||||
case '/':
|
||||
itoa(atoi(vars[c_i].data) / atoi(vars[c_i+1].data), vars[c_i+1].data, 10);
|
||||
break;
|
||||
}
|
||||
c_i++;
|
||||
}
|
||||
//printf(" = %s\n", vars[c_i].data);
|
||||
strcpy(return_string, vars[c_i].data);
|
||||
break;
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
buffer[b_i] = string[s_i];
|
||||
b_i++;
|
||||
break;
|
||||
}
|
||||
s_i++;
|
||||
}
|
||||
while (var_i >= 0) {
|
||||
free(vars[var_i--].data);
|
||||
}
|
||||
}
|
||||
|
||||
void doVarSet(struct Var *var, const char *string) {
|
||||
if (var->data)
|
||||
free(var);
|
||||
var->bytes = strlen(string)+1;
|
||||
var->data = malloc(var->bytes);
|
||||
memcpy(var->data, string, var->bytes);
|
||||
}
|
||||
|
||||
// TODO: use vprintf stuff for arguments (or get byte offsets?)
|
||||
char *doFunction(const char *function, const char *arguments) {
|
||||
/* get our args from buffer, delimited by ',' */
|
||||
int ba_i = 0;
|
||||
char args[2][31];
|
||||
int a_i = 0;
|
||||
int arg_offset = 0;
|
||||
if (arguments[ba_i] != '\0')
|
||||
arg_offset++;
|
||||
while (arguments[ba_i] != '\0') {
|
||||
switch (arguments[ba_i]) {
|
||||
case ',':
|
||||
args[arg_offset][a_i] = '\0';
|
||||
a_i = 0;
|
||||
arg_offset++;
|
||||
break;
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
args[arg_offset][a_i++] = arguments[ba_i];
|
||||
break;
|
||||
}
|
||||
ba_i++;
|
||||
}
|
||||
args[arg_offset][a_i] = '\0';
|
||||
/* okay, let's do the rolling. TODO: handle lack of args */
|
||||
if (arg_offset > 0)
|
||||
printf("passed arg 0: %s\n", args[0]);
|
||||
|
||||
printf("running function:\n%s\n-------\n", function);
|
||||
|
||||
struct VarTable *local_vars = newVarTable(127);
|
||||
|
||||
int b_i = 0; // buffer iterator
|
||||
int bt_i = 0; // buffer type iterator
|
||||
char buffer[255]; // buffer that holds the portion being processed
|
||||
|
||||
char current_var[31]; // vars cannae have more than 31 chars
|
||||
char current_value[31];
|
||||
current_var[0] = '\0';
|
||||
int mode = 0;
|
||||
|
||||
struct Var vars[31]; // max 31 variables
|
||||
int var_i = 0;
|
||||
int c_i = 0; // current var iterator
|
||||
|
||||
int f_i = 0; // function char pos
|
||||
int l_i = 0; // line pos
|
||||
int l_c = 0; // line count
|
||||
size_t f_bytes = 0;
|
||||
char *f_return = malloc(1);
|
||||
while (function[f_i] != '\0') {
|
||||
switch(function[f_i]) {
|
||||
case '\n':
|
||||
l_c++;
|
||||
break;
|
||||
case ' ': // skip space
|
||||
break;
|
||||
case '=':
|
||||
buffer[b_i] = '\0';
|
||||
b_i = 0;
|
||||
strcpy(current_var, buffer);
|
||||
memset(&buffer, 0, 255);
|
||||
mode = VAR_SET;
|
||||
break;
|
||||
case ';':
|
||||
if (mode == VAR_SET) {
|
||||
buffer[b_i++] = ';';
|
||||
buffer[b_i] = '\0';
|
||||
b_i = 0;
|
||||
doOperation(local_vars, &args, arg_offset, current_value, buffer);
|
||||
addVar(local_vars, current_var, current_value);
|
||||
} else if (mode == RETURN) {
|
||||
buffer[b_i] = '\0';
|
||||
b_i = 0;
|
||||
strcpy(current_var, buffer);
|
||||
f_bytes = strlen(getVar(local_vars, current_var))+1;
|
||||
realloc(f_return, f_bytes);
|
||||
memcpy(f_return, getVar(local_vars, current_var), f_bytes);
|
||||
freeVarTable(local_vars); // free up all our local stuff
|
||||
return f_return;
|
||||
}
|
||||
break;
|
||||
case '.':
|
||||
if (b_i == 0) {
|
||||
mode = RETURN;
|
||||
} else {
|
||||
buffer[b_i++] = function[f_i];
|
||||
}
|
||||
break;
|
||||
default:
|
||||
buffer[b_i++] = function[f_i];
|
||||
break;
|
||||
}
|
||||
f_i++; // next char in func
|
||||
}
|
||||
freeVarTable(local_vars); // free up all our local stuff
|
||||
return f_return;
|
||||
}
|
||||
|
||||
char *callFunction(const char *f_name, const char *f_args) {
|
||||
return (doFunction(getVar(function_table, f_name), f_args));
|
||||
}
|
||||
|
||||
char *parseAndCallFunction(struct VarTable *var_table, const char *buffer) {
|
||||
int b_i = 0;
|
||||
char f_name[32];
|
||||
char f_args[63];
|
||||
int f_i = 0;
|
||||
int mode = 0;
|
||||
|
||||
while (buffer[b_i] != '\0') {
|
||||
switch (buffer[b_i]) {
|
||||
case '(':
|
||||
f_name[f_i] = '\0';
|
||||
f_i = 0;
|
||||
mode = 1;
|
||||
break;
|
||||
case ')':
|
||||
f_args[f_i] = '\0';
|
||||
f_i = 0;
|
||||
mode = 2;
|
||||
break;
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
if (mode == 0) {
|
||||
f_name[f_i++] = buffer[b_i];
|
||||
} else if (mode > 0) {
|
||||
f_args[f_i++] = buffer[b_i];
|
||||
// do something with args...
|
||||
}
|
||||
break;
|
||||
}
|
||||
b_i++;
|
||||
}
|
||||
/* convert args son */
|
||||
// FIXME: hackish, q'n'd
|
||||
b_i = 0;
|
||||
char args[10][31];
|
||||
int a_i = 0;
|
||||
int arg_offset = 0;
|
||||
while (f_args[b_i] != '\0') {
|
||||
switch (f_args[b_i]) {
|
||||
case ',':
|
||||
args[arg_offset][a_i] = '\0';
|
||||
a_i = 0;
|
||||
arg_offset++;
|
||||
break;
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
args[arg_offset][a_i++] = f_args[b_i];
|
||||
break;
|
||||
}
|
||||
b_i++;
|
||||
}
|
||||
args[arg_offset][a_i] = '\0';
|
||||
if (f_args[0] != '\0') {
|
||||
a_i = 0;
|
||||
f_i = 0;
|
||||
b_i = 0;
|
||||
while (a_i <= arg_offset) {
|
||||
if (!isdigit(args[a_i][0])) {
|
||||
strcpy(args[a_i], getVar(var_table, args[a_i]));
|
||||
}
|
||||
//printf("%d = %s\n", a_i, args[a_i]);
|
||||
b_i = 0;
|
||||
while (args[a_i][b_i] != '\0') {
|
||||
f_args[f_i++] = args[a_i][b_i++];
|
||||
}
|
||||
if (a_i != arg_offset)
|
||||
f_args[f_i++] = ',';
|
||||
a_i++;
|
||||
}
|
||||
}
|
||||
f_args[f_i] = '\0';
|
||||
if (f_name[0] == '_') {
|
||||
//printf("trying to run %s\n", f_name);
|
||||
return runFunc(g_functions, f_name)(f_args);
|
||||
} else {
|
||||
// TODO: callFunction should parse f_args as well.
|
||||
return callFunction(f_name, f_args);
|
||||
}
|
||||
//return callFunction(f_name, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
int addFunction(const char *buffer) {
|
||||
char func_name[32];
|
||||
int f_size = 128;
|
||||
char *func_data = malloc(f_size*sizeof(char)); // start w/ 128 chars
|
||||
int f_i = 0; // func_data index offset
|
||||
int c_i = 0; // iterator for function_name
|
||||
int i = 0; // iterator for the buffer
|
||||
int depth = 0;
|
||||
while (buffer[i] != '\0') {
|
||||
switch (buffer[i]) {
|
||||
case ' ':
|
||||
break;
|
||||
case '{':
|
||||
if (depth == 0)
|
||||
func_name[c_i] = '\0';
|
||||
depth++;
|
||||
break;
|
||||
case '}':
|
||||
depth--;
|
||||
break;
|
||||
default:
|
||||
if (depth == 0) {
|
||||
func_name[c_i++] = buffer[i];
|
||||
} else if (depth > 0) {
|
||||
// resize if function surpasses our temp func_data buffer
|
||||
if (f_i+1 >= f_size) {
|
||||
f_size += 128;
|
||||
realloc(func_data, f_size);
|
||||
}
|
||||
func_data[f_i] = buffer[i];
|
||||
f_i++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
func_data[f_i] = '\0';
|
||||
addVar(function_table, func_name, func_data);
|
||||
free(func_data);
|
||||
return 0; // should handle errors for malloc...
|
||||
}
|
||||
|
||||
char *doRoll(const char *buffer) {
|
||||
/* get our args from buffer, delimited by ',' */
|
||||
int b_i = 0;
|
||||
char args[2][31];
|
||||
int a_i = 0;
|
||||
int arg_offset = 0;
|
||||
while (buffer[b_i] != '\0') {
|
||||
switch (buffer[b_i]) {
|
||||
case ',':
|
||||
args[arg_offset][a_i] = '\0';
|
||||
a_i = 0;
|
||||
arg_offset++;
|
||||
break;
|
||||
case ' ':
|
||||
break;
|
||||
default:
|
||||
args[arg_offset][a_i++] = buffer[b_i];
|
||||
break;
|
||||
}
|
||||
b_i++;
|
||||
}
|
||||
args[arg_offset][a_i] = '\0';
|
||||
/* okay, let's do the rolling. TODO: handle lack of args */
|
||||
int count = atoi(args[0]);
|
||||
int faces = atoi(args[1]);
|
||||
int total = 0;
|
||||
while (count > 0) {
|
||||
total += (rand() % faces + 1);
|
||||
count--;
|
||||
}
|
||||
/* return char array pointer that will be freed outside of this func */
|
||||
char *f_return = malloc(24);
|
||||
itoa(total, f_return, 10);
|
||||
return f_return;
|
||||
}
|
||||
|
||||
int main() {
|
||||
function_table = newVarTable(255);
|
||||
|
||||
g_functions = newFuncTable(127); // function pointers
|
||||
addFunc(g_functions, "_roll", doRoll);
|
||||
|
||||
/* #define'd function */
|
||||
addFunction(TEST_FULL_FUNC);
|
||||
|
||||
addFunction(ROLL_FUNC);
|
||||
|
||||
char *f_return;
|
||||
f_return = callFunction("test", "");
|
||||
printf("called func \"%s\" returned:\n%s\n", "test", f_return);
|
||||
free(f_return);
|
||||
|
||||
/* free hand this ish */
|
||||
addFunction("add { var = 1 + 2; .var; }");
|
||||
f_return = callFunction("add", "");
|
||||
printf("called func \"%s\" returned:\n%s\n", "add", f_return);
|
||||
free(f_return);
|
||||
|
||||
addFunction(TEST_FUNC_CALL);
|
||||
f_return = callFunction("fcall", "");
|
||||
printf("called func \"%s\" returned:\n%s\n", "fcall", f_return);
|
||||
free(f_return);
|
||||
|
||||
char user_input[1024];
|
||||
printf("Enter script:\n> ");
|
||||
//scanf("%s", user_input);
|
||||
fgets(user_input, 1024, stdin);
|
||||
f_return = doFunction(user_input, "");
|
||||
printf("return:\n%s\n", f_return);
|
||||
free(f_return);
|
||||
|
||||
freeVarTable(function_table);
|
||||
freeFuncTable(g_functions);
|
||||
|
||||
/* char *f_return;
|
||||
f_return = doFunction(TEST_FUNC, NULL, NULL, NULL, NULL);
|
||||
printf("return: %s\n", f_return);
|
||||
free(f_return);*/
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,52 @@
|
|||
/****** t2d.c
|
||||
This test program converts a text file containing ts tile set declarations into various Data structures.
|
||||
******/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "../data.h"
|
||||
|
||||
int fileToMemory(char **buffer, char *file_name) {
|
||||
int i, n, pos = 0;
|
||||
char t_buf[16];
|
||||
|
||||
FILE *file = fopen(file_name, "r");
|
||||
fseek(file, 0, SEEK_END);
|
||||
int size = ftell(file);
|
||||
fseek(file, 0, SEEK_SET);
|
||||
|
||||
char *new_buffer = malloc(size);
|
||||
while ((n = fread(t_buf, 1, 16, file))) {
|
||||
for (i = 0; i < n; i++) {
|
||||
new_buffer[pos++] = t_buf[i];
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
*buffer = new_buffer;
|
||||
return size;
|
||||
}
|
||||
|
||||
int main() {
|
||||
char *buffer;
|
||||
int size = fileToMemory(&buffer, "tiles.txt");
|
||||
|
||||
struct Data *data = loadDataFromMemory(buffer, size);
|
||||
free(buffer);
|
||||
|
||||
printf("total tile sets: %d\n", data->set_count);
|
||||
|
||||
int count = 0;
|
||||
while (count < data->size) {
|
||||
int count_2 = 0;
|
||||
if (data->set[count]) {
|
||||
while (count_2 < data->set[count]->size) {
|
||||
if (data->set[count]->tile[count_2]) {
|
||||
printf("%d:%d\n", count, count_2);
|
||||
}
|
||||
count_2++;
|
||||
}
|
||||
}
|
||||
count++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
0 {
|
||||
0 {
|
||||
name small key
|
||||
type 0
|
||||
}
|
||||
1 {
|
||||
name not a small key
|
||||
type 1
|
||||
armor 12
|
||||
}
|
||||
}
|
||||
|
||||
1 {
|
||||
0 {
|
||||
name lol
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
0 {
|
||||
name small macana
|
||||
required_slots w1
|
||||
damage_mod P1d4
|
||||
skill slashing
|
||||
}
|
||||
|
||||
1 {
|
||||
name large macana
|
||||
required_slots w2
|
||||
damage_mod P1d8
|
||||
skill slashing
|
||||
}
|
||||
|
||||
16 {
|
||||
name cloth armour
|
||||
required_slots T1
|
||||
armour_mod P1
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
0 {
|
||||
name small key
|
||||
type 0
|
||||
}
|
|
@ -0,0 +1,20 @@
|
|||
; slots should be able to copy from base - e.g., "humanoid"=>H1N2S2T1A2a2h2w2d10 etc.
|
||||
0 {
|
||||
name nupi
|
||||
faction chthonic
|
||||
party nupii
|
||||
vision 4
|
||||
behavior 0
|
||||
hp 2+1d4
|
||||
stats S6D6C8I4W4C4
|
||||
slots T1w2
|
||||
; inventories are line delimited with second comma delimited value pertaining to a 0-100 spawn chance
|
||||
equipment {
|
||||
; [target tile name OR "tid:id"], [0-int count of item], [0-100 percentage chance]
|
||||
small macana, 1, 10
|
||||
cloth armour, 1, 25
|
||||
}
|
||||
inventory {
|
||||
gold, 1-3, 5
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue