diff --git a/Makefile b/Makefile index 12cc914..38c4a53 100644 --- a/Makefile +++ b/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 diff --git a/data.c b/data.c new file mode 100644 index 0000000..5129f90 --- /dev/null +++ b/data.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 +#include +#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; +} diff --git a/data.h b/data.h new file mode 100644 index 0000000..89161a8 --- /dev/null +++ b/data.h @@ -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 diff --git a/test/Makefile b/test/Makefile new file mode 100644 index 0000000..2f69d73 --- /dev/null +++ b/test/Makefile @@ -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 diff --git a/test/script.c b/test/script.c new file mode 100644 index 0000000..c4f35a4 --- /dev/null +++ b/test/script.c @@ -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 +#include +#include +#include +#include // 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; +} diff --git a/test/t2d.c b/test/t2d.c new file mode 100644 index 0000000..d36d589 --- /dev/null +++ b/test/t2d.c @@ -0,0 +1,52 @@ +/****** t2d.c + This test program converts a text file containing ts tile set declarations into various Data structures. +******/ +#include +#include +#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; +} diff --git a/test/tiles.txt b/test/tiles.txt new file mode 100644 index 0000000..5761b88 --- /dev/null +++ b/test/tiles.txt @@ -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 + } +} diff --git a/xibalba/equips b/xibalba/equips new file mode 100644 index 0000000..12255ba --- /dev/null +++ b/xibalba/equips @@ -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 +} diff --git a/xibalba/items b/xibalba/items new file mode 100644 index 0000000..5b489dd --- /dev/null +++ b/xibalba/items @@ -0,0 +1,4 @@ +0 { + name small key + type 0 +} diff --git a/xibalba/npcs b/xibalba/npcs new file mode 100644 index 0000000..f59640a --- /dev/null +++ b/xibalba/npcs @@ -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 + } +}