After much struggling due to a fool's lack of documentation, the tile_editor is now (seemingly) fully functional. Changes to tile entries can now be made by adding/deleting/modifying the UI elements and pressing the 'commit changes' button. This only does a change for the TileData, etc., stored in ram. These changes can be saved to a file by specifying a filename in the data field and pressing the 'save' button. On a more technical note, fixed some bugs in the data reading code, such as inventory lines being partially read but then being assigned as a simple key=>string pair rather than an InventoryData struct - this, of course, caused segfaults and was particularly mystifying. Table structs now also have a 'count' property that is incremented or decremented whenever a TablePair is added.

master
kts 2014-01-20 02:21:15 -08:00
parent 9fe34501b5
commit 149cd25ef9
5 changed files with 257 additions and 174 deletions

173
data.c
View File

@ -56,6 +56,56 @@ struct Data *loadDataFromMemory(char *memory, int size) {
return data;
}
int saveDataToFile(struct Data* data, const char *filename) {
FILE *output = fopen(filename, "w");
if (output == NULL) {
return -1;
}
int chars = 0;
int count = 0;
while (count < data->size) {
int count_2 = 0;
if (data->set[count]) {
chars += fprintf(output, "%d {\n", count);
while (count_2 < data->set[count]->size) {
if (data->set[count]->tile[count_2]) {
chars += fprintf(output, "%d {\n", count_2);
struct Table *table = data->set[count]->tile[count_2]->table;
int i = 0;
while (i < table->size) {
struct TablePair *table_pair = table->pair[i];
while (table_pair != NULL) {
if (table_pair->type == T_STRING) {
chars += fprintf(output, "%s %s\n", table_pair->key, table_pair->value);
} else if (table_pair->type == T_INT) {
chars += fprintf(output, "%s %d\n", table_pair->key, *(int*)table_pair->value);
} else if (table_pair->type == T_FLOAT) {
chars += fprintf(output, "%s %f\n", table_pair->key, *(float*)table_pair->value);
} else if (table_pair->type == T_PROTO_INVENTORY) {
chars += fprintf(output, "%s {\n", table_pair->key);
struct InventoryData* inv = table_pair->value;
while (inv != NULL) {
chars += fprintf(output, "%s, %d-%d, %f\n", inv->name, inv->count.min, inv->count.max, inv->chance);
inv = inv->next;
}
chars += fprintf(output, "}\n");
}
table_pair = table_pair->next;
}
i++;
}
chars += fprintf(output, "}\n");
}
count_2++;
}
chars += fprintf(output, "}\n");
}
count++;
}
fclose(output);
return chars;
}
struct TileSetData *loadTileSetData(int tileset_id, char *memory, int *offset, int *depth) {
struct TileSetData *set_data = malloc(sizeof(struct TileSetData));
set_data->tid = tileset_id;
@ -122,11 +172,8 @@ struct TileSetData *loadTileSetData(int tileset_id, char *memory, int *offset, i
****/
struct TileData *loadTileData(int id, char *memory, int *offset, int *depth) {
struct TileData *tile_data = malloc(sizeof(struct TileData));
struct TileData *tile_data = newTileData(8);
tile_data->id = id;
tile_data->count = 0;
tile_data->size = 8;
tile_data->table = newTable(8);
char var_name[32]; // max 32 chars for var name
char var_value[256]; // max 256 chars for value
@ -155,6 +202,7 @@ struct TileData *loadTileData(int id, char *memory, int *offset, int *depth) {
temp_string[temp_offset_2] = '\0';
struct InventoryData *inv = loadInventoryData(memory, offset, depth);
addTablePairPointer(tile_data->table, temp_string, inv, T_PROTO_INVENTORY);
mode = 0;
}
break;
case '}':
@ -217,6 +265,15 @@ struct TileData *loadTileData(int id, char *memory, int *offset, int *depth) {
return tile_data;
}
struct TileData *newTileData(int size) {
struct TileData *tile_data = malloc(sizeof(struct TileData));
tile_data->id = 0;
tile_data->count = 0;
tile_data->size = size;
tile_data->table = newTable(size);
return tile_data;
}
struct InventoryData *newInventoryData() {
struct InventoryData *inventory_data = malloc(sizeof(struct InventoryData));
inventory_data->tid = 0;
@ -230,6 +287,12 @@ struct InventoryData *newInventoryData() {
return inventory_data;
}
void setInventoryDataName(struct InventoryData *inventory, const char *name) {
int length = strlen(name)+1;
inventory->name = realloc(inventory->name, length);
memcpy(inventory->name, name, length);
}
void freeInventoryData(struct InventoryData *inventory_data) {
struct InventoryData *current_data = inventory_data;
while (current_data != NULL) {
@ -248,7 +311,6 @@ struct InventoryData *loadInventoryData(char *memory, int *offset, int *depth) {
char temp_string[64];
int temp_i = 0;
int mode = 0;
while (*depth > 2) {
switch(memory[*offset]) {
case '{':
@ -342,6 +404,23 @@ struct InventoryData *loadInventoryData(char *memory, int *offset, int *depth) {
return first_data;
}
struct TileSetData *getTileSetData(struct Data *data, int tileset_id) {
if (tileset_id > data->size) {
return NULL;
}
if (data->set[tileset_id] != NULL) {
return data->set[tileset_id];
}
return NULL;
}
/*struct TileData *getTileDataByKey(struct TileSetData *set, char *key) {
int *tid = getTablePairValue(data->set[data_set]->keys, key);
if (tid != NULL) {
return data->set[data_set]->tile[*tid];
}
return NULL;
}*/
void freeTileData(struct TileData *tile_data) {
freeTable(tile_data->table);
free(tile_data);
@ -362,13 +441,16 @@ struct Table *newTable(int size) {
void freeTable(struct Table *table) {
int i = 0;
while (i < table->size) {
freeTablePair(table->pair[i++]);
if (table->pair[i] != NULL) {
freeTablePair(table->pair[i]);
}
i++;
}
free(table->pair);
free(table);
}
int getTableIndex(struct Table *table, char *key) {
int getTableIndex(struct Table *table, const char *key) {
if (key == NULL)
return -1;
int i = 0;
@ -406,7 +488,9 @@ struct TileData *getTileDataById(struct Data *data, int tileset_id, int tile_id)
return NULL;
}
struct TablePair *getTablePair(struct Table *table, char *key) {
struct TablePair *getTablePair(struct Table *table, const char *key) {
if (table == NULL)
return NULL;
struct TablePair *pair = table->pair[getTableIndex(table, key)];
while (pair != NULL) {
if (strcmp(key, pair->key) == 0) {
@ -417,10 +501,34 @@ struct TablePair *getTablePair(struct Table *table, char *key) {
return NULL;
}
/*int deleteTablePair(struct Table *table, char *key) {
int index = getTableIndex(table, key);
struct TablePair *pair = table->pair[index];
if (strcmp(key, pair->key) == 0) {
table->pair[index] = pair->next;
freeTablePair(pair);
return 0;
}
struct TablePair *previous = NULL;
pair = pair->next;
// not yet found, let's go down the chain
while (pair != NULL) {
if (strcmp(key, pair->key) == 0) {
// found it, now let's free and repair the Table
previous->next = pair->next;
freeTablePair(pair);
return 0;
}
previous = pair;
pair = pair->next;
}
return -1; // if we reach here, that means it didn't exist
}*/
/**** getTablePairValue
Attempts to return the TablePair value of given key. If the TablePair's type is of T_INT, T_FLOAT, or other such values, the
****/
void *getTablePairValue(struct Table *table, char *key) {
void *getTablePairValue(struct Table *table, const char *key) {
struct TablePair *pair = getTablePair(table, key);
if (pair != NULL) {
return pair->value;
@ -428,7 +536,7 @@ void *getTablePairValue(struct Table *table, char *key) {
return NULL;
}
int addTablePair(struct Table *table, char *key, void *value, int value_size, int type) {
int addTablePair(struct Table *table, const char *key, void *value, int value_size, int type) {
if (key == NULL || value == NULL)
return -10;
int index = getTableIndex(table, key);
@ -436,8 +544,10 @@ int addTablePair(struct Table *table, char *key, void *value, int value_size, in
struct TablePair *table_pair = malloc(sizeof(struct TablePair));
if (table_pair == NULL)
return -1;
table_pair->next = NULL;
setTablePair(table_pair, key, value, value_size, type);
table->pair[index] = table_pair;
table->count++;
} else {
struct TablePair *current_pair = table->pair[index];
while (1) {
@ -449,8 +559,10 @@ int addTablePair(struct Table *table, char *key, void *value, int value_size, in
struct TablePair *table_pair = malloc(sizeof(struct TablePair));
if (table_pair == NULL)
return -2;
table_pair->next = NULL;
setTablePair(table_pair, key, value, value_size, type);
current_pair->next = table_pair;
table->count++;
break;
} else {
current_pair = current_pair->next;
@ -461,7 +573,40 @@ int addTablePair(struct Table *table, char *key, void *value, int value_size, in
return 0;
}
int addTablePairPointer(struct Table *table, char *key, void *value, int type) {
int deleteTablePair(struct Table *table, char *key) {
if (key == NULL)
return -10;
int index = getTableIndex(table, key);
if (table->pair[index] == NULL) {
// does not exist
return -1;
} else {
struct TablePair *current_pair = table->pair[index];
struct TablePair *last_pair = NULL;
while (1) {
if (strcmp(key, current_pair->key) == 0) {
// we have a match, so let's repair the chain if needed
if (current_pair->next != NULL) {
last_pair->next = current_pair->next;
}
freeTablePair(current_pair);
table->count--;
break;
} else {
if (current_pair->next == NULL) {
// does not exist
return -1;
} else {
last_pair = current_pair;
current_pair = current_pair->next;
}
}
}
}
return 0;
}
int addTablePairPointer(struct Table *table, const char *key, void *value, int type) {
if (key == NULL || value == NULL)
return -10;
int index = getTableIndex(table, key);
@ -471,6 +616,7 @@ int addTablePairPointer(struct Table *table, char *key, void *value, int type) {
return -1;
setTablePairPointer(table_pair, key, value, type);
table->pair[index] = table_pair;
table->count++;
} else {
struct TablePair *current_pair = table->pair[index];
while (1) {
@ -484,6 +630,7 @@ int addTablePairPointer(struct Table *table, char *key, void *value, int type) {
return -2;
setTablePairPointer(table_pair, key, value, type);
current_pair->next = table_pair;
table->count++;
break;
} else {
current_pair = current_pair->next;
@ -494,7 +641,7 @@ int addTablePairPointer(struct Table *table, char *key, void *value, int type) {
return 0;
}
void setTablePair(struct TablePair *table_pair, char *key, void *value, int value_size, int type) {
void setTablePair(struct TablePair *table_pair, const char *key, void *value, int value_size, int type) {
int key_size = strlen(key)+1;
table_pair->key = malloc(key_size);
memcpy(table_pair->key, key, key_size);
@ -506,7 +653,7 @@ void setTablePair(struct TablePair *table_pair, char *key, void *value, int valu
table_pair->next = NULL;
}
void setTablePairPointer(struct TablePair *table_pair, char *key, void *value, int type) {
void setTablePairPointer(struct TablePair *table_pair, const char *key, void *value, int type) {
int key_size = strlen(key)+1;
table_pair->key = malloc(key_size);
memcpy(table_pair->key, key, key_size);

22
data.h
View File

@ -39,6 +39,8 @@ struct TileSetData {
struct TileData **tile;
};
struct TileSetData *getTileSetData(struct Data *data, int tileset_id);
struct TileData {
int tid; // tileset id, inherited from TileSetData during load
int id; // id of tile
@ -46,6 +48,7 @@ struct TileData {
int size; // max amount of entries
struct Table *table;
};
struct TileData *newTileData(int size);
struct Range {
int min;
@ -65,8 +68,10 @@ struct InventoryData {
struct InventoryData *next;
};
struct InventoryData *newInventoryData();
struct InventoryData *loadInventoryData(char *memory, int *offset, int *depth);
void freeInventoryData(struct InventoryData *inventory_data);
void setInventoryDataName(struct InventoryData *inventory, const char *name);
struct Data *loadDataFromMemory(char *memory, int size);
struct TileSetData *loadTileSetData(int tileset_id, char *memory, int *offset, int *depth);
@ -79,6 +84,7 @@ void freeTileData(struct TileData *tile_data);
*/
struct Table {
int size;
int count;
struct TablePair **pair;
};
@ -92,16 +98,18 @@ struct TablePair {
struct Table *newTable(int size);
void freeTable(struct Table *table);
int getTableIndex(struct Table *table, char *key);
int getTableIndex(struct Table *table, const char *key);
int addTablePair(struct Table *table, char *key, void *value, int value_size, int type);
int addTablePairPointer(struct Table *table, char *key, void *value, int type);
void setTablePair(struct TablePair *table_pair, char *key, void *value, int value_size, int type);
void setTablePairPointer(struct TablePair *table_pair, char *key, void *value, int type);
struct TablePair *getTablePair(struct Table *table, char *key);
void *getTablePairValue(struct Table *table, char *key);
int addTablePair(struct Table *table, const char *key, void *value, int value_size, int type);
int addTablePairPointer(struct Table *table, const char *key, void *value, int type);
int deleteTablePair(struct Table *table, char *key);
void setTablePair(struct TablePair *table_pair, const char *key, void *value, int value_size, int type);
void setTablePairPointer(struct TablePair *table_pair, const char *key, void *value, int type);
struct TablePair *getTablePair(struct Table *table, const char *key);
void *getTablePairValue(struct Table *table, const char *key);
void freeTablePair(struct TablePair *table_pair);
int fileToMemory(char **buffer, const char *file_name);
int saveDataToFile(struct Data* data, const char *filename);
#endif

View File

@ -71,7 +71,7 @@ int interfaceInit() {
input_graphics = newElement(TYPE_TEXT_INPUT);
setElementPosition(input_graphics, getElementWidth(text_graphics) + font.width + 4, 2 + font.height*4);
setElementCallback(input_graphics, &loadGraphicsCallback);
setElementSize(input_graphics, 16);
setElementSize(input_graphics, 27);
addElementToList(menu_elements, input_graphics);
button_graphics = newElement(TYPE_BUTTON);
@ -89,7 +89,7 @@ int interfaceInit() {
input_data = newElement(TYPE_TEXT_INPUT);
setElementPosition(input_data, getElementWidth(text_data) + font.width + 4, 2 + font.height*6);
setElementCallback(input_data, &loadDataCallback);
setElementSize(input_data, 16);
setElementSize(input_data, 27);
addElementToList(menu_elements, input_data);
button_data = newElement(TYPE_BUTTON);
@ -841,7 +841,16 @@ void loadDataCallback() {
}
void saveDataCallback() {
printConsole("saving data");
char temp[256];
sprintf(temp, "saving data to %s", getElementText(input_data));
printConsole(temp);
int return_value;
if ((return_value = saveDataToFile(tiles_data, getElementText(input_data))) > 0) {
sprintf(temp, "OK(%d), data saved to %s!", return_value, getElementText(input_data));
} else {
sprintf(temp, "ERR(%d), could not save to %s", return_value, getElementText(input_data));
}
printConsole(temp);
}
void loadTile(int set, int id) {
@ -887,15 +896,13 @@ void loadTile(int set, int id) {
drawElement(button_add_pair);
drawElement(button_commit);
struct TileData *tile = getTileDataById(tiles_data, set, id);
if (tile == NULL) {
sprintf(temp, "tile %d:%d does not exist(yet!)\n", set, id);
printConsole(temp);
return;
}
sprintf(temp, "loaded %d:%d(%s)\n", set, id, getTablePairValue(tile->table, "name"));
sprintf(temp, "loaded %d:%d(%s)\n", set, id, (char*)getTablePairValue(tile->table, "name"));
int i;
int j = 0;
@ -1360,9 +1367,18 @@ void commitChangesCallback(struct Element *element) {
int min_count = 0;
int max_count = 0;
int chance = 0;
// TODO: something like clearTileData(Data*, int set, int id);
// then getTileDataById(Data*, int set, int id);
// then various addTablePair calls, as well as addInventoryData(getTilePairValue(?, current_key), current_value, min_count, max_count, chance);
/* completely delete old TileData */
struct TileData *tile = getTileDataById(tiles_data, g_set, g_id);
if (tile != NULL) {
freeTileData(tile);
tiles_data->set[g_set]->tile[g_id] = NULL;
}
/* create new TileData for commit rewrite */
tile = newTileData(8);
tile->id = g_id;
tiles_data->set[g_set]->tile[g_id] = tile;
while (current != NULL) {
switch(current->id) {
case ID_DELETE:
@ -1373,6 +1389,7 @@ void commitChangesCallback(struct Element *element) {
case ID_VALUE:
current_value = getElementText(current);
printf("%s=>%s\n", current_key, current_value);
addTablePair(tile->table, current_key, (void*)current_value, strlen(current_value)+1, T_STRING);
break;
case ID_ITEM_NAME_VAL:
current_value = getElementText(current);
@ -1385,6 +1402,30 @@ void commitChangesCallback(struct Element *element) {
break;
case ID_ITEM_CHANCE_VAL:
chance = getElementValue(current);
struct TablePair *pair = getTablePair(tile->table, current_key);
if (pair != NULL) {
// inventory exists, walk down the chain and append new InventoryData
if (pair->type == T_PROTO_INVENTORY) {
struct InventoryData *inv = pair->value;
while (inv->next != NULL) {
inv = inv->next;
}
struct InventoryData *inventory = newInventoryData();
inventory->count.min = min_count;
inventory->count.max = max_count;
inventory->chance = chance;
setInventoryDataName(inventory, current_value);
inv->next = inventory;
}
} else {
// inventory does not exist, create it
struct InventoryData *inventory = newInventoryData();
inventory->count.min = min_count;
inventory->count.max = max_count;
inventory->chance = chance;
setInventoryDataName(inventory, current_value);
addTablePairPointer(tile->table, current_key, inventory, T_PROTO_INVENTORY);
}
printf("%s=>%s, %d-%d @ %d\n", current_key, current_value, min_count, max_count, chance);
break;
default:
@ -1392,6 +1433,11 @@ void commitChangesCallback(struct Element *element) {
}
current = current->next;
}
// table has no key=>value pairs, thus meaning there are no elements - free & remove it!
if (tile->table->count <= 0) {
freeTileData(tile);
tiles_data->set[g_set]->tile[g_id] = NULL;
}
char temp[128];
sprintf(temp, "Changes committed for %d:%d", g_set, g_id);
printConsole(temp);

View File

@ -1,119 +0,0 @@
0 {
0 {
name warrior
race human
vision 16
stats S8D8C8I8W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
}
1 {
name mage
}
7 {
name medicine man
race manitou
stats S8D8C8I8W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
}
12 {
name shock trooper
race ibexian
stats S10D8C10I6W6c6
slots H1F1N2S2A2a2h2D8w2T1W1L2l2o2
equipment {
large macana, 1, 100.0
}
}
17 {
name barbarian
race ibexian
stats S12D10C10I4W4c4
slots H1F1N2S2A2a2h2D8w2T1W1L2l2o2
equipment {
large macana, 1, 100.0
cloth armour, 1, 100.0
}
}
18 {
name warrior
race quosqoy
stats S8D8C10I8W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
}
28 {
name gunner
race quosqo
stats S6D8C10I10W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
}
}
1 {
0 {
name nupi
faction chthonic
party nupii
vision 4
behavior 0
hp 2+1d4
stats S6D6C8I4W4C4
slots T1w2
equipment {
small macana, 1, 10.0
cloth armour, 1, 25
}
inventory {
gold, 1-3, 5.0
}
}
}
2 {
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
}
}
3 {
0 {
name small key
type 0
}
1 {
name gold
value 1
}
}
4 {
0 {
name wooden door
state 0
}
}
5 {
0 {
name stone floor
}
1 {
name wood floor
}
}
6 {
0 {
name stone wall
}
1 {
name wood wall
}
}

View File

@ -1,69 +1,73 @@
0 {
0 {
vision 16
equipment {
macana, 1-1, 100.000000
}
name warrior
race human
vision 16
stats S8D8C8I8W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
inventory {
gold, 4-12, 80.000000
acco leaves, 1-3, 50.000000
}
1 {
name mage
stats S8D8C8I8W8c8
}
7 {
name medicine man
race manitou
stats S8D8C8I8W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
stats S8D8C8I8W8c8
}
12 {
equipment {
large macana, 1-1, 100.000000
}
name shock trooper
race ibexian
stats S10D8C10I6W6c6
slots H1F1N2S2A2a2h2D8w2T1W1L2l2o2
equipment {
large macana, 1, 100.0
}
stats S10D8C10I6W6c6
}
17 {
equipment {
large macana, 1-1, 100.000000
cloth armour, 1-1, 100.000000
}
name barbarian
race ibexian
stats S12D10C10I4W4c4
slots H1F1N2S2A2a2h2D8w2T1W1L2l2o2
equipment {
large macana, 1, 100.0
cloth armour, 1, 100.0
}
stats S12D10C10I4W4c4
}
18 {
name warrior
race quosqoy
stats S8D8C10I8W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
stats S8D8C10I8W8c8
}
28 {
name gunner
race quosqo
stats S6D8C10I10W8c8
slots H1F1N2S2A2a2h2D8w2T1W1L2l2f2
stats S6D8C10I10W8c8
}
}
1 {
0 {
name nupi
faction chthonic
party nupii
vision 4
behavior 0
hp 2+1d4
stats S6D6C8I4W4C4
slots T1w2
equipment {
small macana, 1, 10.0
cloth armour, 1, 25
small macana, 1-1, 10.000000
cloth armour, 1-1, 25.000000
}
name nupi
faction chthonic
slots T1w2
inventory {
gold, 1-3, 5.0
gold, 1-3, 5.000000
}
stats S6D6C8I4W4C4
}
}
2 {
@ -105,9 +109,6 @@ state 0
0 {
name stone floor
}
1 {
name wood floor
}
}
6 {
0 {