#include #include #include #include #include #include #include #include #include #include #include #include #include "consts.h" #include "base.h" #include "display.h" #include "edit.h" int edit_cell_count = 2; cell** all_loaded_cells; int n_loaded = -1; int zoom_factor = 200 ; void link_cells(cell* parent, cell* child) { if(parent != NULL) { if(parent->next_1 == NULL) { parent->next_1 = child; } else if(parent->next_2 == NULL) { parent->next_2 = child; } else if(parent->next_3 == NULL) { parent->next_3 = child; } else if(parent->next_4 == NULL) { parent->next_4 = child; } else { fprintf(stderr, "Unable to link cell : parent is at full capacity.\n"); } }; if(child != NULL) { if(child->prev_1 == NULL) { child->prev_1 = parent; } else if(child->prev_2 == NULL) { child->prev_2 = parent; } else if(child->prev_3 == NULL) { child->prev_3 = parent; } else if(child->prev_4 == NULL) { child->prev_4 = parent; } else { fprintf(stderr, "Unable to link cell : child is at full capacity.\n"); } } } void unlink_cells(cell* parent, cell* child) { if(parent != NULL) { if(parent->next_1 == child) { parent->next_1 = NULL; } else if(parent->next_2 == child) { parent->next_2 = NULL; } else if(parent->next_3 == child) { parent->next_3 = NULL; } else if(parent->next_4 == child) { parent->next_4 = NULL; } else { fprintf(stderr, "Unable to unlink cell : no link found.\n"); } }; if(child != NULL) { if(child->prev_1 == parent) { child->prev_1 = NULL; } else if(child->prev_2 == parent) { child->prev_2 = NULL; } else if(child->prev_3 == parent) { child->prev_3 = NULL; } else if(child->prev_4 == parent) { child->prev_4 = NULL; } else { fprintf(stderr, "Unable to unlink cell : no link found.\n"); } }; } cell* redirect_cell(cell* cl) { if(cl != NULL) { if(cl->prev_1 != NULL) { return cl->prev_1; } else if(cl->prev_2 != NULL) { return cl->prev_2; } else if(cl->prev_3 != NULL) { return cl->prev_3; } else if(cl->prev_4 != NULL) { return cl->prev_4; } else { fprintf(stderr, "Unable to redirect cell : no parent.\n"); } } } void append_cell(int cell_type, int X, int Y, cell* parent) { cell* new = malloc(sizeof(cell)); new->id = parent->id; // mostly for parkour new->unique_id = edit_cell_count; new->coord_x = X; new->coord_y = Y; new->star_allowed = is_star_allowed(cell_type); new->type = (CELLTYPE)cell_type ; new->prev_1 = NULL ; new->prev_2 = NULL; new->prev_3 = NULL; new->prev_4 = NULL; new->next_1 = NULL; new->next_2 = NULL; new->next_3 = NULL; new->next_4 = NULL; char* meta = "none"; edit_cell_count += 1; link_cells(parent, new); cell_count[cell_type] += 1; } void append_cell_orthogonal(int cell_type, char dir, cell* parent) { if(dir == 'N' || dir == 'n') { append_cell(cell_type, parent->coord_x, parent->coord_y + tile_size * 2, parent); } else if(dir == 'E' || dir == 'e') { append_cell(cell_type, parent->coord_x + tile_size * 2, parent->coord_y, parent); } else if(dir == 'W' || dir == 'w') { append_cell(cell_type, parent->coord_x - tile_size * 2, parent->coord_y, parent); } else if(dir == 'S' || dir == 's') { append_cell(cell_type, parent->coord_x, parent->coord_y - tile_size * 2, parent); } else { fprintf(stderr, "ERROR : invalid direction (%d)", dir); } } void destroy_cell() { cell* new_current = redirect_cell(current); unlink_cells(current, current->next_1); unlink_cells(current, current->next_2); unlink_cells(current, current->next_3); unlink_cells(current, current->next_4); unlink_cells(current->prev_1, current); unlink_cells(current->prev_2, current); unlink_cells(current->prev_3, current); unlink_cells(current->prev_4, current); cell_count[(int)current->type] -= 1; free(current); current = new_current ; } bool isAdding = false ; int editBuffer = 0 ; int phase = 0 ; int editCellType = 0 ; int editDirection = 0 ; // -------------------------------- // bool isLinking = false ; cell* par ; cell* chd ; // -------------------------------- // bool confirmRemove = false ; bool cooldownRemove = false ; void playerEditActions(bool* finished) { SDL_Event event; while(SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: break; case SDL_KEYDOWN: if(cooldownRemove) { cooldownRemove = false; } else { confirmRemove = false ; }; switch (event.key.keysym.sym) { case SDLK_1: if(!isAdding && current->next_1 != NULL) { current = current->next_1; } else if (isAdding) { editBuffer *= 10; editBuffer += 1; }; break; case SDLK_2: if(!isAdding && current->next_2 != NULL) { current = current->next_2; } else if (isAdding) { editBuffer *= 10; editBuffer += 2; }; break; case SDLK_3: if(!isAdding && current->next_3 != NULL) { current = current->next_3; } else if (isAdding) { editBuffer *= 10; editBuffer += 3; }; break; case SDLK_4: if(!isAdding && current->next_4 != NULL) { current = current->next_4; } else if (isAdding) { editBuffer *= 10; editBuffer += 4; }; break; case SDLK_0: if(!isAdding && current->prev_1 != NULL) { current = current->prev_1; } else if (isAdding) { editBuffer *= 10; }; break; case SDLK_9: if(!isAdding && current->prev_2 != NULL) { current = current->prev_2; } else if (isAdding) { editBuffer *= 10; editBuffer += 9; }; break; case SDLK_8: if(!isAdding && current->prev_3 != NULL) { current = current->prev_3; } else if (isAdding) { editBuffer *= 10; editBuffer += 8; }; break; case SDLK_7: if(!isAdding && current->prev_4 != NULL) { current = current->prev_4; } else if (isAdding) { editBuffer *= 10; editBuffer += 7; }; break; case SDLK_6: if (isAdding) { editBuffer *= 10; editBuffer += 6; }; break; case SDLK_5: if (isAdding) { editBuffer *= 10; editBuffer += 5; }; break; case SDLK_BACKSPACE: if (isAdding) { editBuffer = editBuffer / 10; }; break; case SDLK_SPACE: if(isAdding) { if(phase == 0) { editCellType = editBuffer%n_cell_type; } else if(phase == 1) { editDirection = editBuffer%4; phase = -1; isAdding = false; char dir ; if(editDirection == 0) { dir = 's'; } else if(editDirection == 1) { dir = 'e'; } else if(editDirection == 2) { dir = 'n'; } else if(editDirection == 3) { dir = 'w'; }; append_cell_orthogonal(editCellType, dir, current); }; phase += 1; editBuffer = 0; } else if(isLinking) { if(phase == 0) { par = current ; } else if(phase == 1) { if(current != par) { chd = current; link_cells(par, chd); phase = -1; isLinking = false; } else { phase -= 1; } }; phase += 1; }; break; case SDLK_p: if(!isLinking) { isAdding = true ; phase = 0 ; printf("now adding...\n"); }; break; case SDLK_l: if(!isAdding) { isLinking = true; phase = 0 ; printf("now linking...\n"); }; break; case SDLK_r: if(!confirmRemove) { confirmRemove = true ; cooldownRemove = true ; } else { destroy_cell(); confirmRemove = false ; cooldownRemove = false ; }; break; case SDLK_TAB: if(isAdding || isLinking || confirmRemove) { isAdding = false; isLinking = false; confirmRemove = false; cooldownRemove = false ; } else { *finished = true; }; break; case SDLK_s: save("level.csv"); printf("Saved level\n"); break; case SDLK_q: load("level.csv"); printf("loaded level\n"); break; case SDLK_F2: zoom_factor = min(zoom_factor + 50, 1250) ; break; case SDLK_F3: zoom_factor = max(zoom_factor - 50, 50) ; break; case SDLK_e: current->type = (CELLTYPE)(((int)current->type +1)%n_cell_type); break; } } } } void draw_types(SDL_Renderer* renderer) { drawStringToRenderer(renderer, letters, "start", __width__ - 6 * 75/2, 50, 75/2, 105/2); drawStringToRenderer(renderer, letters, "blue", __width__ - 5 * 75/2, 100, 75/2, 105/2); drawStringToRenderer(renderer, letters, "red", __width__ - 4 * 75/2, 150, 75/2, 105/2); drawStringToRenderer(renderer, letters, "event", __width__ - 6 * 75/2, 200, 75/2, 105/2); drawStringToRenderer(renderer, letters, "vs", __width__ - 3 * 75/2, 250, 75/2, 105/2); drawStringToRenderer(renderer, letters, "bowser", __width__ - 7 * 75/2, 300, 75/2, 105/2); drawStringToRenderer(renderer, letters, "chance", __width__ - 7 * 75/2, 350, 75/2, 105/2); drawStringToRenderer(renderer, letters, "boo", __width__ - 4 * 75/2, 400, 75/2, 105/2); drawStringToRenderer(renderer, letters, "star", __width__ - 5 * 75/2, 450, 75/2, 105/2); drawStringToRenderer(renderer, letters, "bank", __width__ - 5 * 75/2, 500, 75/2, 105/2); drawStringToRenderer(renderer, letters, "shop", __width__ - 5 * 75/2, 550, 75/2, 105/2); } void draw_directions(SDL_Renderer* renderer) { drawStringToRenderer(renderer, letters, "north", __width__ - 6 * 75/2, 50, 75/2, 105/2); drawStringToRenderer(renderer, letters, "east", __width__ - 5 * 75/2, 100, 75/2, 105/2); drawStringToRenderer(renderer, letters, "south", __width__ - 6 * 75/2, 150, 75/2, 105/2); drawStringToRenderer(renderer, letters, "west", __width__ - 5 * 75/2, 200, 75/2, 105/2); } void edit_main(SDL_Renderer* renderer) { bool finished = false; while(!finished) { resetRenderer(renderer); draw_board(renderer, current->coord_x - zoom_factor, current->coord_x + zoom_factor, current->coord_y - zoom_factor, current->coord_y + zoom_factor, current); if(isAdding) { drawStringToRenderer(renderer, letters, "add cell", 50, __height__ - 50, 75/2, 105/2); if(phase == 0) { drawStringToRenderer(renderer, letters, "choose type", 50, 50, 75/2, 105/2); draw_types(renderer); } else { drawStringToRenderer(renderer, letters, "choose direction", 50, 50, 75/2, 105/2); draw_directions(renderer); }; drawNumberToRenderer(renderer, digits, editBuffer, 50, 150, 75/2, 105/2, 0); } else if(isLinking) { drawStringToRenderer(renderer, letters, "link cells", 50, __height__ - 50, 75/2, 105/2); if(phase == 0) { drawStringToRenderer(renderer, letters, "choose parent", 50, 50, 75/2, 105/2); } else { drawStringToRenderer(renderer, letters, "choose child", 50, 50, 75/2, 105/2); } } else if(confirmRemove) { drawStringToRenderer(renderer, letters, "press r again to remove", 50, __height__ - 50, 75/2, 105/2); }; updateRenderer(renderer); playerEditActions(&finished); usleep(20000); } } // save/load level void reassign_id_cell(cell* cl, int* current, int common) { if(cl != NULL && cl->id != 60000) { cl->unique_id = *current; *current += 1; cl->id = 60000; reassign_id_cell(cl->next_1, current, common); reassign_id_cell(cl->next_2, current, common); reassign_id_cell(cl->next_3, current, common); reassign_id_cell(cl->next_4, current, common); } } void reassign_ids() { int p = 1 ; reassign_id_cell(start, &p, start->id); } void write_cell(FILE* ptr, cell* cl, int global_id) { if(cl != NULL && cl->id == global_id) { printf("saving cell %d\n", cl->unique_id); cl->id = global_id+1; fprintf(ptr, "%d,%d,%d,%d,%d[", cl->unique_id, (int)cl->type, cl->coord_x, cl->coord_y, (int)cl->star_allowed); printf("%d,%d,%d,%d,%d[", cl->unique_id, (int)cl->type, cl->coord_x, cl->coord_y, (int)cl->star_allowed); if(cl->next_1 != NULL) { fprintf(ptr, "%d,", cl->next_1->unique_id); printf("%d,", cl->next_1->unique_id); }; if(cl->next_2 != NULL) { fprintf(ptr, "%d,", cl->next_2->unique_id); printf("%d,", cl->next_2->unique_id); }; if(cl->next_3 != NULL) { fprintf(ptr, "%d,", cl->next_3->unique_id); printf("%d,", cl->next_3->unique_id); }; if(cl->next_4 != NULL) { fprintf(ptr, "%d,", cl->next_4->unique_id); printf("%d,", cl->next_4->unique_id); }; fprintf(ptr, "]\n"); printf("]\n"); write_cell(ptr, cl->next_1, global_id); write_cell(ptr, cl->next_2, global_id); write_cell(ptr, cl->next_3, global_id); write_cell(ptr, cl->next_4, global_id); } } void save(char* filename) { reassign_ids(); FILE* ptr = fopen(filename, "w"); write_cell(ptr, start, start->id); fclose(ptr); } // fprintf(ptr, "%d,%d,%d,%d,%d[", cl->unique_id, (int)cl->type, cl->coord_x, cl->coord_y, (int)cl->star_allowed); void load(char* filename) { n_loaded = line_count(filename) -1; all_loaded_cells = malloc(sizeof(cell*)*n_loaded); all_loaded_cells[0] = start; for(int i = 0; i < n_loaded; i++) { if(i != 0) { all_loaded_cells[i] = malloc(sizeof(cell)); }; all_loaded_cells[i]->next_1 = NULL; all_loaded_cells[i]->next_2 = NULL; all_loaded_cells[i]->next_3 = NULL; all_loaded_cells[i]->next_4 = NULL; all_loaded_cells[i]->prev_1 = NULL; all_loaded_cells[i]->prev_2 = NULL; all_loaded_cells[i]->prev_3 = NULL; all_loaded_cells[i]->prev_4 = NULL; }; FILE* ptr = fopen(filename, "r"); char burn; printf("Loading %d lines...\n", n_loaded); for(int i = 0; i < n_loaded; i++) { printf("%d\n", i); int unique = get_integer(ptr); int a_type = get_integer(ptr); int cx = get_integer(ptr); int cy = get_integer(ptr); int ok_star = get_integer(ptr); //printf(" %d, %d, %d, %d, %d\n", unique, a_type, cx, cy, ok_star); all_loaded_cells[i]->unique_id = unique; all_loaded_cells[i]->type = (CELLTYPE)a_type; all_loaded_cells[i]->coord_x = cx; all_loaded_cells[i]->coord_y = cy; all_loaded_cells[i]->star_allowed = (bool)ok_star; int current_link = get_integer(ptr); while(current_link > 0) { link_cells(all_loaded_cells[i], all_loaded_cells[current_link-1]); //printf(" linking %d <--> %d", i, current_link -1); current_link = get_integer(ptr); }; if(i != n_loaded -1) { terminate_line(ptr); } }; current = start; edit_cell_count = n_loaded; fclose(ptr); }