diff options
Diffstat (limited to 'src/editor/editor.cpp')
| -rw-r--r-- | src/editor/editor.cpp | 643 |
1 files changed, 347 insertions, 296 deletions
diff --git a/src/editor/editor.cpp b/src/editor/editor.cpp index 3586629b..aa5a493d 100644 --- a/src/editor/editor.cpp +++ b/src/editor/editor.cpp @@ -105,6 +105,7 @@ struct tilemap { int width; int height; + int render_flags; tile *tiles; }; @@ -116,6 +117,7 @@ static void tilemap_new(tilemap *tm, int width, int height) tm->width = width; tm->height = height; + tm->render_flags = 0; tm->tiles = (tile *)mem_alloc(size, 1); mem_zero(tm->tiles, size); } @@ -219,6 +221,7 @@ static const int MAX_LAYERS = 64; static layer layers[MAX_LAYERS]; static int num_layers = 0; static int current_layer = 0; +static int current_hover_layer = -1; static int layers_remove(int index) { @@ -377,10 +380,20 @@ static tileset *tilesets_get(int index) /******************************************************** UI *********************************************************/ -static void render_tilemap(tilemap *tm, float sx, float sy, float scale) + +static const int TILEMAPFLAG_READONLY = 1; +static const int TILEMAPFLAG_UISPACE = 2; +static const int TILEMAPFLAG_HILIGHTED = 4; + +static void render_tilemap(tilemap *tm, float sx, float sy, float scale, int flags) { float frac = (1.0f/1024.0f); //2.0f; + gfx_quads_begin(); + + if(flags&TILEMAPFLAG_HILIGHTED) + gfx_setcolor(1.0f,0.5f,0.5f,1.0f); + for(int y = 0; y < tm->height; y++) for(int x = 0; x < tm->width; x++) { @@ -444,17 +457,13 @@ static const char *editor_filename = 0; static int editor_mode = 0; // 0 == tiles, 1 == ents static int editor_selected_ent = -1; -static const int TILEMAPFLAG_READONLY = 1; -static const int TILEMAPFLAG_UISPACE = 2; - static int ui_do_tilemap(void *id, tilemap *tm, int flags, float x, float y, float scale) { /* int do_input = 1; - if(inp_key_pressed(input::lalt) || inp_key_pressed(input::ralt)) + if(inp_key_pressed(KEY_LALT) || inp_key_pressed(KEY_RALT)) do_input = 0;*/ - float mx = ui_mouse_world_x(); float my = ui_mouse_world_y(); if(flags&TILEMAPFLAG_UISPACE) @@ -519,14 +528,14 @@ static int ui_do_tilemap(void *id, tilemap *tm, int flags, float x, float y, flo ui_set_hot_item(id); // render the tilemap - render_tilemap(tm, x, y, scale); + render_tilemap(tm, x, y, scale, flags); if(ui_hot_item() == id) { if(brush.tiles != 0) { // draw brush - render_tilemap(&brush, (tmx-brush.width/2)*scale, (tmy-brush.height/2)*scale, scale); + render_tilemap(&brush, (tmx-brush.width/2)*scale, (tmy-brush.height/2)*scale, scale, flags); gfx_texture_set(-1); gfx_blend_additive(); @@ -704,7 +713,171 @@ void draw_editor_button(const void *id, const char *text, int checked, float x, gfx_pretty_text(x+1, y-1, 6.5f, text, -1); } + + +int editor_load(const char *filename) +{ + editor_reset(); + + DATAFILE *df = datafile_load(filename); + if(!df) + return 0; + + // load tilesets + { + int start, count; + datafile_get_type(df, MAPRES_IMAGE, &start, &count); + for(int i = 0; i < count; i++) + { + mapres_image *img = (mapres_image *)datafile_get_item(df, start+i, 0, 0); + void *data = datafile_get_data(df, img->image_data); + int id = tilesets_new(); + void *data_cpy = mem_alloc(img->width*img->height*4, 1); + mem_copy(data_cpy, data, img->width*img->height*4); + tilesets_set_img(id, img->width, img->height, data_cpy); + } + } + + // load tilemaps + { + int start, num; + datafile_get_type(df, MAPRES_TILEMAP, &start, &num); + for(int t = 0; t < num; t++) + { + mapres_tilemap *tmap = (mapres_tilemap *)datafile_get_item(df, start+t,0,0); + //unsigned char *data = (unsigned char *)datafile_get_data(df, tmap->data); + + layer *l = layers_get(layers_new(tmap->width, tmap->height)); + mem_copy(l->tm.tiles, datafile_get_data(df, tmap->data), tmap->width*tmap->height*2); + l->tileset_id = tmap->image; + l->main_layer = tmap->main; + + // force a main layer + if(num == 1) + l->main_layer = 1; + } + } + + // load entities + for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++) + { + // fetch entities of this class + int start, num; + datafile_get_type(df, t, &start, &num); + + for(int i = 0; i < num; i++) + { + mapres_entity *e = (mapres_entity *)datafile_get_item(df, start+i,0,0); + + // map type + int type = 0; + for(int k = 0; ent_types[k].name; k++) + { + if(ent_types[k].id == t && + memcmp(ent_types[k].fields, e->data, ent_types[k].numfields*sizeof(int)) == 0) + { + type = k; + break; + } + } + + //dbg_msg("editor", "ent type=%d pos=(%d,%d)", type, e->x, e->y); + ents_new(type, e->x, e->y); + } + } + + return 1; +} + +int editor_save(const char *filename) +{ + DATAFILE_OUT *df = datafile_create(filename); + + // add tilesets + for(int i = 0; i < tilesets_count(); i++) + { + mapres_image img; + tileset *ts = tilesets_get(i); + img.width = ts->img.width; + img.height = ts->img.height; + img.image_data = datafile_add_data(df, ts->img.width*ts->img.height*4, ts->img.data); + datafile_add_item(df, MAPRES_IMAGE, i, sizeof(img), &img); + } + + // add tilemaps + for(int i = 0; i < layers_count(); i++) + { + layer *l = layers_get(i); + mapres_tilemap tm; + tm.image = l->tileset_id; + tm.width = l->tm.width; + tm.height = l->tm.height; + tm.x = 0; + tm.y = 0; + tm.main = l->main_layer; + tm.scale = 1<<16; + tm.data = datafile_add_data(df, l->tm.width*l->tm.height*2, l->tm.tiles); + datafile_add_item(df, MAPRES_TILEMAP, i, sizeof(tm), &tm); + } + + // add collision + char *collisiondata = 0x0; + for(int i = 0; i < layers_count(); i++) + { + layer *l = layers_get(i); + if(l->main_layer) + { + mapres_collision col; + col.width = l->tm.width; + col.height = l->tm.height; + + collisiondata = (char *)mem_alloc(col.width*col.height, 1); + for(int y = 0, c = 0; y < col.height; y++) + for(int x = 0; x < col.width; x++, c++) + { + if(l->tm.tiles[c].index) + collisiondata[c] = 1; + else + collisiondata[c] = 0; + } + + col.data_index = datafile_add_data(df, col.width*col.height, collisiondata); + datafile_add_item(df, MAPRES_COLLISIONMAP, 0, sizeof(col), &col); + break; + } + } + + // add entities + for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++) + { + int id = 0; + for(int i = 0; i < ents_count(); i++) + { + entity *ent = ents_get(i); + if(ent_types[ent->type].id != t) + continue; + + int savebuf[64]; + mapres_entity *mapent = (mapres_entity *)savebuf; + mapent->x = ent->x; + mapent->y = ent->y; + dbg_msg("editor", "saving ent idx=%d pos=(%d,%d)", i, ent->x, ent->y); + memcpy(mapent->data, ent_types[ent->type].fields, ent_types[ent->type].numfields*sizeof(int)); + datafile_add_item(df, t, id, (ent_types[ent->type].numfields+2)*sizeof(int), mapent); + id++; + } + } + + // finish and clean up + datafile_finish(df); + mem_free(collisiondata); + + return 0; +} + + static int editor_loadimage = -1; +static int editor_loadmap = -1; static void editor_listdir_callback(const char *name, int is_dir, void *user) { @@ -729,8 +902,8 @@ static void editor_listdir_callback(const char *name, int is_dir, void *user) static void editor_render_loadfile_dialog() { - gfx_clear(0.2f,0.2f,0.8f); // GUI coordsys + gfx_clear(0.2f,0.2f,0.8f); gfx_mapscreen(0,0,400.0f,300.0f); int index = 0; @@ -740,14 +913,38 @@ static void editor_render_loadfile_dialog() editor_loadimage = -1; } -static void editor_render() +static void editor_listdir_map_callback(const char *name, int is_dir, void *user) { - if(editor_loadimage != -1) - { - editor_render_loadfile_dialog(); + if(name[0] == '.') // skip this shit! return; + + int *y = (int*)user; + if(ui_do_button((void*)(*y + 1), name, 0, 10, 10 + *y * 8, 100, 6, draw_editor_button, 0)) + { + char buf[512]; + sprintf(buf, "data/maps/%s", name); + + editor_load(buf); + editor_loadmap = -1; } + *y += 1; +} + +static void editor_render_loadmap_dialog() +{ + // GUI coordsys + gfx_clear(0.2f,0.2f,0.8f); + gfx_mapscreen(0,0,400.0f,300.0f); + int index = 0; + fs_listdir("data/maps", editor_listdir_map_callback, &index); + + if(inp_key_pressed(KEY_ESC)) + editor_loadmap = -1; +} + +static void editor_render_normal() +{ // background color gfx_clear(0.2f,0.2f,0.8f); @@ -762,22 +959,26 @@ static void editor_render() gfx_texture_set(-1); if(l->tileset_id >= 0 && l->tileset_id < tilesets_count()) gfx_texture_set(tilesets_get(l->tileset_id)->tex_id); + + int f = 0; + if(current_hover_layer == i) + f = TILEMAPFLAG_HILIGHTED; if(editor_mode == 0) { if(l == layers_get_current()) { // do current layer - ui_do_tilemap(&l->tm, &l->tm, 0, 0, 0, 32.0f); + ui_do_tilemap(&l->tm, &l->tm, f, 0, 0, 32.0f); } else if(l->visible) { // render layer - render_tilemap(&l->tm, 0, 0, 32.0f); + render_tilemap(&l->tm, 0, 0, 32.0f, f); } } else - render_tilemap(&l->tm, 0, 0, 32.0f); + render_tilemap(&l->tm, 0, 0, 32.0f, f); } if(editor_mode == 1) @@ -805,6 +1006,8 @@ static void editor_render() float layerbox_y = 0; int count = 1; int main_layer = -1; + + current_hover_layer = -1; for(int i = 0; i < layers_count(); i++) { layer *l = layers_get(i); @@ -833,6 +1036,9 @@ static void editor_render() layers_get(i)->visible = layers_get(i)->visible^1; // layer bytton + if(ui_mouse_inside(layerbox_x+8, layerbox_y+i*14, toolbox_width-8, 12)) + current_hover_layer = i; + if(ui_do_button(&layers_get(i)->tileset_id, buf, current_layer == i, layerbox_x+8, layerbox_y+i*14, toolbox_width-8, 12, draw_editor_button, 0)) current_layer = i; } @@ -972,313 +1178,165 @@ static void editor_render() if(ui_do_button(&del, "Del", 0, 0, y, toolbox_width, 6, draw_editor_button, 0)) ents_delete(editor_selected_ent); } + } -int editor_load(const char *filename) +static void editor_render() { - DATAFILE *df = datafile_load(filename); - if(!df) - return 0; - - // load tilesets - { - int start, count; - datafile_get_type(df, MAPRES_IMAGE, &start, &count); - for(int i = 0; i < count; i++) - { - mapres_image *img = (mapres_image *)datafile_get_item(df, start+i, 0, 0); - void *data = datafile_get_data(df, img->image_data); - int id = tilesets_new(); - void *data_cpy = mem_alloc(img->width*img->height*4, 1); - mem_copy(data_cpy, data, img->width*img->height*4); - tilesets_set_img(id, img->width, img->height, data_cpy); - } - } + if(editor_loadimage != -1) + editor_render_loadfile_dialog(); + else if(editor_loadmap != -1) + editor_render_loadmap_dialog(); + else + editor_render_normal(); - // load tilemaps + // render butt ugly mouse cursor + float mx = ui_mouse_x(); + float my = ui_mouse_y(); + gfx_texture_set(-1); + gfx_quads_begin(); + gfx_setcolor(0,0,0,1); + gfx_quads_draw_freeform(mx,my,mx,my, + mx+7,my, + mx,my+7); + gfx_setcolor(1,1,1,1); + gfx_quads_draw_freeform(mx+1,my+1,mx+1,my+1, + mx+5,my+1, + mx+1,my+5); + gfx_quads_end(); +} + +extern "C" void editor_update_and_render() +{ + static int mouse_x = 0; + static int mouse_y = 0; + + // handle mouse movement + float mx, my, mwx, mwy; + int rx, ry; { - int start, num; - datafile_get_type(df, MAPRES_TILEMAP, &start, &num); - for(int t = 0; t < num; t++) - { - mapres_tilemap *tmap = (mapres_tilemap *)datafile_get_item(df, start+t,0,0); - //unsigned char *data = (unsigned char *)datafile_get_data(df, tmap->data); - - layer *l = layers_get(layers_new(tmap->width, tmap->height)); - mem_copy(l->tm.tiles, datafile_get_data(df, tmap->data), tmap->width*tmap->height*2); - l->tileset_id = tmap->image; - l->main_layer = tmap->main; - - // force a main layer - if(num == 1) - l->main_layer = 1; - } + inp_mouse_relative(&rx, &ry); + mouse_x += rx; + mouse_y += ry; + if(mouse_x < 0) mouse_x = 0; + if(mouse_y < 0) mouse_y = 0; + if(mouse_x > gfx_screenwidth()) mouse_x = gfx_screenwidth(); + if(mouse_y > gfx_screenheight()) mouse_y = gfx_screenheight(); + + // update the ui + mx = (mouse_x/(float)gfx_screenwidth())*400.0f; + my = (mouse_y/(float)gfx_screenheight())*300.0f; + mwx = world_offset_x+mx*world_zoom; // adjust to zoom and offset + mwy = world_offset_y+my*world_zoom; // adjust to zoom and offset + + int buttons = 0; + if(inp_key_pressed(KEY_MOUSE_1)) buttons |= 1; + if(inp_key_pressed(KEY_MOUSE_2)) buttons |= 2; + if(inp_key_pressed(KEY_MOUSE_3)) buttons |= 4; + + ui_update(mx,my,mwx,mwy,buttons); } - // load entities - for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++) + // render the editor + editor_render(); + + if(inp_key_pressed(KEY_LALT) || inp_key_pressed(KEY_RALT)) { - // fetch entities of this class - int start, num; - datafile_get_type(df, t, &start, &num); + // steal focus + static int moveid; + ui_set_hot_item(&moveid); - for(int i = 0; i < num; i++) + if(inp_key_pressed(KEY_MOUSE_1)) { - mapres_entity *e = (mapres_entity *)datafile_get_item(df, start+i,0,0); - - // map type - int type = 0; - for(int k = 0; ent_types[k].name; k++) - { - if(ent_types[k].id == t && - memcmp(ent_types[k].fields, e->data, ent_types[k].numfields*sizeof(int)) == 0) - { - type = k; - break; - } - } - - //dbg_msg("editor", "ent type=%d pos=(%d,%d)", type, e->x, e->y); - ents_new(type, e->x, e->y); + world_offset_x -= rx*2; + world_offset_y -= ry*2; } } - return 1; -} + // + if(inp_key_pressed(KEY_F1)) + inp_mouse_mode_absolute(); + if(inp_key_pressed(KEY_F2)) + inp_mouse_mode_relative(); -int editor_save(const char *filename) -{ - DATAFILE_OUT *df = datafile_create(filename); - - // add tilesets - for(int i = 0; i < tilesets_count(); i++) + // mode switch + if(inp_key_down(KEY_TAB)) + editor_mode ^= 1; + + // zoom in + if(inp_key_down(KEY_KP_ADD)) { - mapres_image img; - tileset *ts = tilesets_get(i); - img.width = ts->img.width; - img.height = ts->img.height; - img.image_data = datafile_add_data(df, ts->img.width*ts->img.height*4, ts->img.data); - datafile_add_item(df, MAPRES_IMAGE, i, sizeof(img), &img); + world_zoom--; + if(world_zoom < 3) + world_zoom = 3; } - // add tilemaps - for(int i = 0; i < layers_count(); i++) + // zoom out + if(inp_key_down(KEY_KP_SUBTRACT)) { - layer *l = layers_get(i); - mapres_tilemap tm; - tm.image = l->tileset_id; - tm.width = l->tm.width; - tm.height = l->tm.height; - tm.x = 0; - tm.y = 0; - tm.main = l->main_layer; - tm.scale = 1<<16; - tm.data = datafile_add_data(df, l->tm.width*l->tm.height*2, l->tm.tiles); - datafile_add_item(df, MAPRES_TILEMAP, i, sizeof(tm), &tm); + world_zoom++; + if(world_zoom > 8) + world_zoom = 8; } - // add collision - char *collisiondata = 0x0; - for(int i = 0; i < layers_count(); i++) + if(inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL)) { - layer *l = layers_get(i); - if(l->main_layer) + if(inp_key_down('L')) { - mapres_collision col; - col.width = l->tm.width; - col.height = l->tm.height; - - collisiondata = (char *)mem_alloc(col.width*col.height, 1); - for(int y = 0, c = 0; y < col.height; y++) - for(int x = 0; x < col.width; x++, c++) + int w = 50, h = 50; + for(int i = 0; i < layers_count(); i++) + { + layer *l = layers_get(i); + if(l->main_layer) { - if(l->tm.tiles[c].index) - collisiondata[c] = 1; - else - collisiondata[c] = 0; + w = l->tm.width; + h = l->tm.height; + break; } - - col.data_index = datafile_add_data(df, col.width*col.height, collisiondata); - datafile_add_item(df, MAPRES_COLLISIONMAP, 0, sizeof(col), &col); - break; + } + // copy main layer size + layers_new(w, h); } - } - - // add entities - for(int t = MAPRES_ENTS_START; t < MAPRES_ENTS_END; t++) - { - int id = 0; - for(int i = 0; i < ents_count(); i++) + + if(inp_key_down('O')) + editor_loadmap = 1; + + if(inp_key_down('S')) { - entity *ent = ents_get(i); - if(ent_types[ent->type].id != t) - continue; - - int savebuf[64]; - mapres_entity *mapent = (mapres_entity *)savebuf; - mapent->x = ent->x; - mapent->y = ent->y; - dbg_msg("editor", "saving ent idx=%d pos=(%d,%d)", i, ent->x, ent->y); - memcpy(mapent->data, ent_types[ent->type].fields, ent_types[ent->type].numfields*sizeof(int)); - datafile_add_item(df, t, id, (ent_types[ent->type].numfields+2)*sizeof(int), mapent); - id++; + dbg_msg("editor", "save"); + editor_save(editor_filename); } + } - // finish and clean up - datafile_finish(df); - mem_free(collisiondata); + if(inp_key_down(KEY_F5)) + { + dbg_msg("editor", "quick save"); + editor_save("quicksave.map"); + } - return 0; + if(inp_key_down(KEY_F8)) + { + dbg_msg("editor", "quick load"); + int s = current_layer; + editor_reset(); + editor_load("quicksave.map"); + current_layer = s; + if(current_layer >= layers_count()) + current_layer = layers_count(); + + } } -static int editor_loop() +extern "C" void editor_init() { - int mouse_x = 0; - int mouse_y = 0; - - inp_mouse_mode_relative(); - - while(!(inp_key_pressed(KEY_LCTRL) && inp_key_pressed('Q'))) - { - // update input - inp_update(); - - // handle mouse movement - float mx, my, mwx, mwy; - int rx, ry; - { - inp_mouse_relative(&rx, &ry); - mouse_x += rx; - mouse_y += ry; - if(mouse_x < 0) mouse_x = 0; - if(mouse_y < 0) mouse_y = 0; - if(mouse_x > gfx_screenwidth()) mouse_x = gfx_screenwidth(); - if(mouse_y > gfx_screenheight()) mouse_y = gfx_screenheight(); - - // update the ui - mx = (mouse_x/(float)gfx_screenwidth())*400.0f; - my = (mouse_y/(float)gfx_screenheight())*300.0f; - mwx = world_offset_x+mx*world_zoom; // adjust to zoom and offset - mwy = world_offset_y+my*world_zoom; // adjust to zoom and offset - - int buttons = 0; - if(inp_key_pressed(KEY_MOUSE_1)) buttons |= 1; - if(inp_key_pressed(KEY_MOUSE_2)) buttons |= 2; - if(inp_key_pressed(KEY_MOUSE_3)) buttons |= 4; - - ui_update(mx,my,mwx,mwy,buttons); - } - - // - editor_render(); - - if(inp_key_pressed(KEY_LALT) || inp_key_pressed(KEY_RALT)) - { - static int moveid; - ui_set_hot_item(&moveid); - if(inp_key_pressed(KEY_MOUSE_1)) - { - world_offset_x -= rx*2; - world_offset_y -= ry*2; - } - } - - - // render butt ugly mouse cursor - gfx_texture_set(-1); - gfx_quads_begin(); - gfx_setcolor(0,0,0,1); - gfx_quads_draw_freeform(mx,my,mx,my, - mx+7,my, - mx,my+7); - gfx_setcolor(1,1,1,1); - gfx_quads_draw_freeform(mx+1,my+1,mx+1,my+1, - mx+5,my+1, - mx+1,my+5); - gfx_quads_end(); - - // swap the buffers - gfx_swap(); - - // - if(inp_key_pressed(KEY_F1)) - inp_mouse_mode_absolute(); - if(inp_key_pressed(KEY_F2)) - inp_mouse_mode_relative(); - - // mode switch - if(inp_key_down(KEY_TAB)) - editor_mode ^= 1; - - // zoom in - if(inp_key_down(KEY_KP_ADD)) - { - world_zoom--; - if(world_zoom < 3) - world_zoom = 3; - } - - // zoom out - if(inp_key_down(KEY_KP_SUBTRACT)) - { - world_zoom++; - if(world_zoom > 8) - world_zoom = 8; - } - - if(inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL)) - { - if(inp_key_down('L')) - { - int w = 50, h = 50; - for(int i = 0; i < layers_count(); i++) - { - layer *l = layers_get(i); - if(l->main_layer) - { - w = l->tm.width; - h = l->tm.height; - break; - } - } - // copy main layer size - layers_new(w, h); - } - - if(inp_key_down('S')) - { - dbg_msg("editor", "save"); - editor_save(editor_filename); - } - - } - - if(inp_key_down(KEY_F5)) - { - dbg_msg("editor", "quick save"); - editor_save("quicksave.map"); - } - - if(inp_key_down(KEY_F8)) - { - dbg_msg("editor", "quick load"); - int s = current_layer; - editor_reset(); - editor_load("quicksave.map"); - current_layer = s; - if(current_layer >= layers_count()) - current_layer = layers_count(); - - } - - // be nice - thread_sleep(1); - } - - return 0; + // reset and start + font_texture = gfx_load_texture("data/debug_font.png"); + checker_texture = gfx_load_texture("data/checker.png"); + editor_reset(); } +/* extern void modmenu_init(); extern "C" int editor_main(int argc, char **argv) @@ -1310,13 +1368,6 @@ extern "C" int editor_main(int argc, char **argv) if(!gfx_init()) return -1; - modmenu_init(); - - // reset and start - font_texture = gfx_load_texture("data/debug_font.png"); - checker_texture = gfx_load_texture("data/checker.png"); - editor_reset(); - // load or new if(!editor_load(editor_filename)) { @@ -1327,4 +1378,4 @@ extern "C" int editor_main(int argc, char **argv) editor_loop(); return 0; -} +}*/ |