#include #include "State_EntEdit.h" #include "state.h" #include "globals.h" #include "Ui.h" #include "Primitives.h" #include "render.h" #include "fifo.h" #include "EntityData.h" #include "string.h" char *ent_text_name[] = { "Filename: ", "Name: ", "Anim: ", "Set: ", "Face: ", "Frame: ", //////// logic "type: ", "behave: ", //////// movement / collision "mass: ", "radius: ", "speed: ", "turn: ", //////// "hp: ", "sight: ", //////// attack "range: ", "attack: ", "damage: ", "spawn: ", //////// if projectile "time: " }; char *ent_button_name[] = { "Delete", "Duplicate", "Save" }; int openEntEditState() { report(DEBUG, "EntEditState", "opened"); int i; int offset_x, offset_y; offset_x = offset_y = 0; // window and sub-windows ent_window = newBox(16, 16, g_v_width-32, g_v_height-32, 0); ent_window_l = newBox(16, 16, ent_window->w/4, ent_window->h, 0); ent_window_r = newBox(ent_window_l->x+ent_window_l->w, 16, ent_window->w-ent_window_l->w, ent_window->h, 0); // list ent_list = newList(ui_colors); ent_list->box.x = ent_window_l->x; ent_list->box.y = ent_window_l->y; ent_list->box.w = ent_window_l->w; ent_list->box.h = ent_window_l->h - 32; ent_item = NULL; buildEntList(); // text & input offset_x = ent_window_r->x+2; offset_y = ent_window_r->y+2; // first render animation-related stuff for (i = 0; i < ENT_TEXT_ANIMATION_E; i++) { ent_text[i] = newTextt(&g_medium_glyphs, ui_colors, ent_text_name[i]); ent_text[i]->box.x = offset_x; ent_text[i]->box.y = offset_y; ent_input[i] = newTextInput(&g_medium_glyphs, button_colors, ent_window_r->w - ent_text[i]->box.w-4); ent_input[i]->box.x = offset_x + ent_text[i]->box.w+2; ent_input[i]->box.y = offset_y; offset_y += ent_text[i]->box.h + 2; } offset_y += ent_text[0]->box.h; // now logic for (i = ENT_TEXT_ANIMATION_E; i < ENT_TEXT_LOGIC_E; i++) { ent_text[i] = newTextt(&g_medium_glyphs, ui_colors, ent_text_name[i]); ent_text[i]->box.x = offset_x; ent_text[i]->box.y = offset_y; ent_input[i] = newTextInput(&g_medium_glyphs, button_colors, ent_window_r->w - ent_text[i]->box.w-4); ent_input[i]->box.x = offset_x + ent_text[i]->box.w+2; ent_input[i]->box.y = offset_y; offset_y += ent_text[i]->box.h + 2; } offset_y += ent_text[0]->box.h; // now movement for (i = ENT_TEXT_LOGIC_E; i < ENT_TEXT_MOVEMENT_E; i++) { ent_text[i] = newTextt(&g_medium_glyphs, ui_colors, ent_text_name[i]); ent_text[i]->box.x = offset_x; ent_text[i]->box.y = offset_y; ent_input[i] = newTextInput(&g_medium_glyphs, button_colors, ent_window_r->w - ent_text[i]->box.w-4); ent_input[i]->box.x = offset_x + ent_text[i]->box.w+2; ent_input[i]->box.y = offset_y; offset_y += ent_text[i]->box.h + 2; } offset_y += ent_text[0]->box.h; // hp etc. for (i = ENT_TEXT_MOVEMENT_E; i < ENT_TEXT_ETC_E; i++) { ent_text[i] = newTextt(&g_medium_glyphs, ui_colors, ent_text_name[i]); ent_text[i]->box.x = offset_x; ent_text[i]->box.y = offset_y; ent_input[i] = newTextInput(&g_medium_glyphs, button_colors, ent_window_r->w - ent_text[i]->box.w-4); ent_input[i]->box.x = offset_x + ent_text[i]->box.w+2; ent_input[i]->box.y = offset_y; offset_y += ent_text[i]->box.h + 2; } offset_y += ent_text[0]->box.h; // combat for (i = ENT_TEXT_ETC_E; i < ENT_TEXT_COMBAT_E; i++) { ent_text[i] = newTextt(&g_medium_glyphs, ui_colors, ent_text_name[i]); ent_text[i]->box.x = offset_x; ent_text[i]->box.y = offset_y; ent_input[i] = newTextInput(&g_medium_glyphs, button_colors, ent_window_r->w - ent_text[i]->box.w-4); ent_input[i]->box.x = offset_x + ent_text[i]->box.w+2; ent_input[i]->box.y = offset_y; offset_y += ent_text[i]->box.h + 2; } offset_y += ent_text[0]->box.h; // time-related for (i = ENT_TEXT_COMBAT_E; i < ENT_TEXT_COUNT; i++) { ent_text[i] = newTextt(&g_medium_glyphs, ui_colors, ent_text_name[i]); ent_text[i]->box.x = offset_x; ent_text[i]->box.y = offset_y; ent_input[i] = newTextInput(&g_medium_glyphs, button_colors, ent_window_r->w - ent_text[i]->box.w-4); ent_input[i]->box.x = offset_x + ent_text[i]->box.w+2; ent_input[i]->box.y = offset_y; offset_y += ent_text[i]->box.h + 2; } offset_y += ent_text[0]->box.h; ent_input_a = NULL; // button offset_y += ent_text[0]->box.h + 8; for (i = 0; i < ENT_BUTTON_COUNT; i++) { ent_button[i] = newButton(&g_medium_glyphs, button_colors, ent_button_name[i]); ent_button[i]->box.x = offset_x; ent_button[i]->box.y = offset_y - ent_button[i]->box.h; offset_x += ent_button[i]->box.w + 8; } ent_button_a = NULL; return 0; } int closeEntEditState() { int i; // window and sub-windows freeBox(ent_window); freeBox(ent_window_l); freeBox(ent_window_r); // list freeList(ent_list); // text & input for (i = 0; i < ENT_TEXT_COUNT; i++) { freeTextt(ent_text[i]); freeTextInput(ent_input[i]); } // buttons for (i = 0; i < ENT_BUTTON_COUNT; i++) { freeButton(ent_button[i]); } report(DEBUG, "EntEditState", "closed"); return 0; } int processEntEditState() { return 1; } int renderEntEditState() { int i; // window and sub-windows renderSQuad(ent_window->x, ent_window->y, ent_window->w, ent_window->h, ui_colors->a_bg); renderSQuad(ent_window_l->x, ent_window_l->y, ent_window_l->w, ent_window_l->h, ui_colors->bg); renderSQuad(ent_window_r->x, ent_window_r->y, ent_window_r->w, ent_window_r->h, ui_colors->bg); // list renderList(ent_list); // text & input for (i = 0; i < ENT_TEXT_COUNT; i++) { renderTextt(ent_text[i]); renderTextInput(ent_input[i]); } for (i = 0; i < ENT_BUTTON_COUNT; i++) { renderButton(ent_button[i]); } return 1; } int handleEntEditState(SDL_Event event) { int i; switch(event.type) { case SDL_KEYDOWN: if (event.key.keysym.sym == SDLK_ESCAPE) { popState(g_state_manager); } if (ent_input_a != NULL) { if (event.key.keysym.sym == SDLK_LEFT) { if (ent_input_a->cursor > 0) { ent_input_a->cursor--; } } else if (event.key.keysym.sym == SDLK_RIGHT) { if (ent_input_a->cursor < strlen(ent_input_a->text)) { ent_input_a->cursor++; } } else if (event.key.keysym.sym == SDLK_BACKSPACE) { if (ent_input_a->cursor != 0) { deleteTextInput(ent_input_a, ent_input_a->cursor-1, 1); ent_input_a->cursor--; } } } break; case SDL_TEXTINPUT: if (ent_input_a != NULL) { insertTextInput(ent_input_a, event.text.text); } break; case SDL_MOUSEBUTTONDOWN: if (ent_input_a != NULL) { ent_input_a->flags &= ~UI_ACTIVE; ent_input_a = NULL; SDL_StopTextInput(); } // check input for (i = 0; i < ENT_TEXT_COUNT; i++) { if (inBox(ent_input[i]->box, event.motion.x, event.motion.y)) { ent_input_a = ent_input[i]; ent_input_a->flags |= UI_ACTIVE; SDL_Rect rect = { ent_input_a->box.x, ent_input_a->box.y, ent_input_a->box.w, ent_input_a->box.h }; SDL_SetTextInputRect(&rect); SDL_StartTextInput(); } } // check buttons for (i = 0; i < ENT_BUTTON_COUNT; i++) { if (inBox(ent_button[i]->box, event.motion.x, event.motion.y)) { ent_button_a = ent_button[i]; ent_button_a->flags |= UI_ACTIVE; } } // check list if (inBox(ent_list->box, event.motion.x, event.motion.y)) { for (i = 0; i < ent_list->count; i++) { if (inBox(getListItemBoxAbs(ent_list, i), event.motion.x, event.motion.y)) { if (ent_item != NULL) { if (ent_item != ent_list->items[i]) { ent_item->flags &= ~UI_ACTIVE; } else { break; } } ent_item = ent_list->items[i]; ent_item->flags |= UI_ACTIVE; openEntItem(); break; } } } break; case SDL_MOUSEBUTTONUP: if (ent_button_a != NULL) { if (inBox(ent_button_a->box, event.motion.x, event.motion.y)) { if (ent_button_a == ent_button[ENT_BUTTON_SAVE]) { saveEntItem(); } else if (ent_button_a == ent_button[ENT_BUTTON_DELETE]) { deleteEntItem(); } buildEntList(); } ent_button_a->flags &= ~UI_ACTIVE; ent_button_a = NULL; } break; } return 1; } // ================================================================ void buildEntList() { freeListItems(ent_list); int i = 0; struct Dir *dir = openDir(ENT_DIR, 0); struct DirEntry *entry; while ((entry = readDir(dir)) != NULL) { if (!hasExtension(entry->d_name, ENT_EXT)) continue; struct Ui_Colors *colors = (++i % 2 == 1 ? ui_colors : button_colors); addListItem(ent_list, newButton(&g_small_glyphs, colors, entry->d_name)); } closeDir(dir); } void openEntItem() { char *filename = NULL; filename = setStringF(filename, "%s%s", ENT_DIR, ent_item->text); //printf("filename is %s(%d)!\n", filename, strlen(filename)); struct EntityData *entity_data = newEntityData(); loadEntityData(entity_data, filename); // filename & anim setTextInputText(ent_input[ENT_TEXT_FILENAME], "%s", ent_item->text); setTextInputText(ent_input[ENT_TEXT_NAME], "%s", entity_data->name); setTextInputText(ent_input[ENT_TEXT_ANIM], "%s", entity_data->anim); setTextInputText(ent_input[ENT_TEXT_SET], "%s", entity_data->set); setTextInputText(ent_input[ENT_TEXT_FACE], "%s", entity_data->face); setTextInputText(ent_input[ENT_TEXT_FRAME], "%d", entity_data->frame); // logic setTextInputText(ent_input[ENT_TEXT_TYPE], "%d", entity_data->type); setTextInputText(ent_input[ENT_TEXT_BEHAVE], "%d", entity_data->behave); // movement setTextInputText(ent_input[ENT_TEXT_MASS], "%f", entity_data->mass); setTextInputText(ent_input[ENT_TEXT_RADIUS], "%f", entity_data->radius); setTextInputText(ent_input[ENT_TEXT_SPEED], "%f", entity_data->speed); setTextInputText(ent_input[ENT_TEXT_TURN], "%f", entity_data->turn); // hp etc setTextInputText(ent_input[ENT_TEXT_HP], "%d", entity_data->hp); setTextInputText(ent_input[ENT_TEXT_SIGHT], "%f", entity_data->sight); // combat setTextInputText(ent_input[ENT_TEXT_RANGE], "%f", entity_data->range); setTextInputText(ent_input[ENT_TEXT_ATKTYPE], "%d", entity_data->attack); setTextInputText(ent_input[ENT_TEXT_DAMAGE], "%d", entity_data->damage); setTextInputText(ent_input[ENT_TEXT_SPAWN], "%s", entity_data->spawn); // time setTextInputText(ent_input[ENT_TEXT_TIME], "%d", entity_data->time); freeEntityData(entity_data); free(filename); } void saveEntItem() { struct EntityData *entity_data = newEntityData(); char *filename = malloc(1); // filename & animation filename = setStringF(filename, "%s%s", ENT_DIR, ent_input[ENT_TEXT_FILENAME]->text); entity_data->filename = copyString(entity_data->filename, filename); entity_data->name = copyString(entity_data->name, ent_input[ENT_TEXT_NAME]->text); entity_data->anim = copyString(entity_data->anim, ent_input[ENT_TEXT_ANIM]->text); entity_data->set = copyString(entity_data->set, ent_input[ENT_TEXT_SET]->text); entity_data->face = copyString(entity_data->face, ent_input[ENT_TEXT_FACE]->text); entity_data->frame = atoi(ent_input[ENT_TEXT_FRAME]->text); // logic entity_data->type = atoi(ent_input[ENT_TEXT_TYPE]->text); entity_data->behave = atoi(ent_input[ENT_TEXT_BEHAVE]->text); // movement & size entity_data->mass = atof(ent_input[ENT_TEXT_MASS]->text); entity_data->radius = atof(ent_input[ENT_TEXT_RADIUS]->text); entity_data->speed = atof(ent_input[ENT_TEXT_SPEED]->text); entity_data->turn = atof(ent_input[ENT_TEXT_TURN]->text); // hp, etc. entity_data->hp = atoi(ent_input[ENT_TEXT_HP]->text); entity_data->sight = atof(ent_input[ENT_TEXT_SIGHT]->text); // combat entity_data->range = atof(ent_input[ENT_TEXT_RANGE]->text); entity_data->attack = atoi(ent_input[ENT_TEXT_ATKTYPE]->text); entity_data->damage = atoi(ent_input[ENT_TEXT_DAMAGE]->text); entity_data->spawn = copyString(entity_data->spawn, ent_input[ENT_TEXT_SPAWN]->text); // time entity_data->time = atoi(ent_input[ENT_TEXT_TIME]->text); // saveEntityData(entity_data); freeEntityData(entity_data); free(filename); } void deleteEntItem() { if (ent_item != NULL) { char *filename = malloc(1); filename[0] = '\0'; filename = catStringF(filename, "%s%s", ENT_DIR, ent_input[ENT_TEXT_FILENAME]->text); deleteFile(filename); free(filename); } }