diff options
Diffstat (limited to 'src/game')
| -rw-r--r-- | src/game/client/gc_client.cpp | 133 | ||||
| -rw-r--r-- | src/game/client/gc_menu.cpp | 1144 | ||||
| -rw-r--r-- | src/game/client/gc_ui.cpp | 282 | ||||
| -rw-r--r-- | src/game/client/gc_ui.h | 64 | ||||
| -rwxr-xr-x | src/game/editor/array.h | 238 | ||||
| -rw-r--r-- | src/game/editor/ed_layer_game.cpp | 20 | ||||
| -rw-r--r-- | src/game/editor/ed_layer_quads.cpp | 361 | ||||
| -rw-r--r-- | src/game/editor/ed_layer_tiles.cpp | 294 | ||||
| -rw-r--r-- | src/game/editor/editor.cpp | 2501 | ||||
| -rw-r--r-- | src/game/editor/editor.hpp | 569 |
10 files changed, 4826 insertions, 780 deletions
diff --git a/src/game/client/gc_client.cpp b/src/game/client/gc_client.cpp index 9c70bd86..295b729f 100644 --- a/src/game/client/gc_client.cpp +++ b/src/game/client/gc_client.cpp @@ -5,8 +5,8 @@ #include <string.h> extern "C" { - #include <engine/client/ec_ui.h> #include <engine/e_config.h> + #include <engine/client/ec_font.h> }; #include "../g_game.h" @@ -18,6 +18,7 @@ extern "C" { #include "gc_menu.h" #include "gc_skin.h" #include "gc_render.h" +#include "gc_ui.h" // sound channels enum @@ -47,8 +48,6 @@ enum CHATMODE_REMOTECONSOLE, }; -RECT *ui2_screen(); - static int chat_mode = CHATMODE_NONE; bool menu_active = false; bool menu_game_active = false; @@ -568,6 +567,14 @@ void render_loading(float percent); extern "C" void modc_init() { + static FONT_SET default_font; + + int before = gfx_memory_usage(); + font_set_load(&default_font, "fonts/default_font%d.tfnt", "fonts/default_font%d.png", "fonts/default_font%d_b.png", 14, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 36); + dbg_msg("font", "gfx memory usage: %d", gfx_memory_usage()-before); + + gfx_text_set_default_font(&default_font); + menu_init(); // setup sound channels @@ -1669,16 +1676,16 @@ static void render_player( // render name plate if(!info.local && config.cl_nameplates) { - //gfx_pretty_text_color + //gfx_text_color float a = 1; if(config.cl_nameplates_always == 0) a = clamp(1-powf(distance(local_target_pos, position)/200.0f,16.0f), 0.0f, 1.0f); const char *name = client_datas[info.clientid].name; - float tw = gfx_pretty_text_width(28.0f, name, -1); - gfx_pretty_text_color(1,1,1,a); - gfx_pretty_text(position.x-tw/2.0f, position.y-60, 28.0f, name, -1); - gfx_pretty_text_color(1,1,1,1); + float tw = gfx_text_width(0, 28.0f, name, -1); + gfx_text_color(1,1,1,a); + gfx_text(0, position.x-tw/2.0f, position.y-60, 28.0f, name, -1); + gfx_text_color(1,1,1,1); } } @@ -1940,13 +1947,13 @@ void render_goals(float x, float y, float w) { char buf[64]; sprintf(buf, "Time Limit: %d min", gameobj->time_limit); - gfx_pretty_text(x+w/2, y, 24.0f, buf, -1); + gfx_text(0, x+w/2, y, 24.0f, buf, -1); } if(gameobj && gameobj->score_limit) { char buf[64]; sprintf(buf, "Score Limit: %d", gameobj->score_limit); - gfx_pretty_text(x+40, y, 24.0f, buf, -1); + gfx_text(0, x+40, y, 24.0f, buf, -1); } } @@ -1983,7 +1990,7 @@ void render_spectators(float x, float y, float w) } } - gfx_pretty_text(x+10, y, 32, buffer, (int)w-20); + gfx_text(0, x+10, y, 32, buffer, (int)w-20); } void render_scoreboard(float x, float y, float w, int team, const char *title) @@ -2011,22 +2018,22 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) title = "Score Board"; } - float tw = gfx_pretty_text_width(48, title, -1); + float tw = gfx_text_width(0, 48, title, -1); if(team == -1) { - gfx_pretty_text(x+w/2-tw/2, y, 48, title, -1); + gfx_text(0, x+w/2-tw/2, y, 48, title, -1); } else { - gfx_pretty_text(x+10, y, 48, title, -1); + gfx_text(0, x+10, y, 48, title, -1); if(gameobj) { char buf[128]; sprintf(buf, "%d", gameobj->teamscore[team&1]); - tw = gfx_pretty_text_width(48, buf, -1); - gfx_pretty_text(x+w-tw-30, y, 48, buf, -1); + tw = gfx_text_width(0, 48, buf, -1); + gfx_text(0, x+w-tw-30, y, 48, buf, -1); } } @@ -2037,7 +2044,7 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) { char buf[128]; sprintf(buf, "%4d", gameobj->teamscore[team&1]); - gfx_pretty_text(x+w/2-tw/2, y, 32, buf, -1); + gfx_text(0, x+w/2-tw/2, y, 32, buf, -1); }*/ @@ -2071,9 +2078,9 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) } // render headlines - gfx_pretty_text(x+10, y, 24.0f, "Score", -1); - gfx_pretty_text(x+125, y, 24.0f, "Name", -1); - gfx_pretty_text(x+w-70, y, 24.0f, "Ping", -1); + gfx_text(0, x+10, y, 24.0f, "Score", -1); + gfx_text(0, x+125, y, 24.0f, "Name", -1); + gfx_text(0, x+w-70, y, 24.0f, "Ping", -1); y += 29.0f; // render player scores @@ -2098,19 +2105,19 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) } sprintf(buf, "%4d", info->score); - gfx_pretty_text(x+60-gfx_pretty_text_width(font_size,buf,-1), y, font_size, buf, -1); + gfx_text(0, x+60-gfx_text_width(0, font_size,buf,-1), y, font_size, buf, -1); if(config.cl_show_player_ids) { sprintf(buf, "%d | %s", info->clientid, client_datas[info->clientid].name); - gfx_pretty_text(x+128, y, font_size, buf, -1); + gfx_text(0, x+128, y, font_size, buf, -1); } else - gfx_pretty_text(x+128, y, font_size, client_datas[info->clientid].name, -1); + gfx_text(0, x+128, y, font_size, client_datas[info->clientid].name, -1); sprintf(buf, "%4d", info->latency); - float tw = gfx_pretty_text_width(font_size, buf, -1); - gfx_pretty_text(x+w-tw-35, y, font_size, buf, -1); + float tw = gfx_text_width(0, font_size, buf, -1); + gfx_text(0, x+w-tw-35, y, font_size, buf, -1); // render avatar if((flags[0] && flags[0]->carried_by == info->clientid) || (flags[1] && flags[1]->carried_by == info->clientid)) @@ -2136,8 +2143,6 @@ void render_scoreboard(float x, float y, float w, int team, const char *title) void mapscreen_to_world(float center_x, float center_y, float zoom) { - //RECT screen = *ui2_screen(); - //const float default_zoom = 1.5f; float width = 300*3*zoom*gfx_screenaspect(); float height = 300*3*zoom; @@ -2730,14 +2735,14 @@ void render_game() continue; float font_size = 48.0f; - float killername_w = gfx_pretty_text_width(font_size, client_datas[killmsgs[r].killer].name, -1); - float victimname_w = gfx_pretty_text_width(font_size, client_datas[killmsgs[r].victim].name, -1); + float killername_w = gfx_text_width(0, font_size, client_datas[killmsgs[r].killer].name, -1); + float victimname_w = gfx_text_width(0, font_size, client_datas[killmsgs[r].victim].name, -1); float x = startx; // render victim name x -= victimname_w; - gfx_pretty_text(x, y, font_size, client_datas[killmsgs[r].victim].name, -1); + gfx_text(0, x, y, font_size, client_datas[killmsgs[r].victim].name, -1); // render victim tee x -= 24.0f; @@ -2800,7 +2805,7 @@ void render_game() // render killer name x -= killername_w; - gfx_pretty_text(x, y, font_size, client_datas[killmsgs[r].killer].name, -1); + gfx_text(0, x, y, font_size, client_datas[killmsgs[r].killer].name, -1); } y += 44; @@ -2827,7 +2832,7 @@ void render_game() sprintf(buf, "Rcon: %s_", chat_input); else sprintf(buf, "Chat: %s_", chat_input); - gfx_pretty_text(x, y, 8.0f, buf, 380); + gfx_text(0, x, y, 8.0f, buf, 380); starty = y; } @@ -2843,35 +2848,35 @@ void render_game() float begin = x; // render name - gfx_pretty_text_color(0.8f,0.8f,0.8f,1); + gfx_text_color(0.8f,0.8f,0.8f,1); if(chat_lines[r].client_id == -1) - gfx_pretty_text_color(1,1,0.5f,1); // system + gfx_text_color(1,1,0.5f,1); // system else if(chat_lines[r].team) - gfx_pretty_text_color(0.45f,0.9f,0.45f,1); // team message + gfx_text_color(0.45f,0.9f,0.45f,1); // team message else if(chat_lines[r].name_color == 0) - gfx_pretty_text_color(1.0f,0.5f,0.5f,1); // red + gfx_text_color(1.0f,0.5f,0.5f,1); // red else if(chat_lines[r].name_color == 1) - gfx_pretty_text_color(0.7f,0.7f,1.0f,1); // blue + gfx_text_color(0.7f,0.7f,1.0f,1); // blue else if(chat_lines[r].name_color == -1) - gfx_pretty_text_color(0.75f,0.5f,0.75f, 1); // spectator + gfx_text_color(0.75f,0.5f,0.75f, 1); // spectator // render line - int lines = int(gfx_pretty_text_width(10, chat_lines[r].text, -1)) / 300 + 1; + int lines = int(gfx_text_width(0, 10, chat_lines[r].text, -1)) / 300 + 1; - gfx_pretty_text(begin, y - 8 * (lines - 1), 8, chat_lines[r].name, -1); - begin += gfx_pretty_text_width(10, chat_lines[r].name, -1); + gfx_text(0, begin, y - 8 * (lines - 1), 8, chat_lines[r].name, -1); + begin += gfx_text_width(0, 10, chat_lines[r].name, -1); - gfx_pretty_text_color(1,1,1,1); + gfx_text_color(1,1,1,1); if(chat_lines[r].client_id == -1) - gfx_pretty_text_color(1,1,0.5f,1); // system + gfx_text_color(1,1,0.5f,1); // system else if(chat_lines[r].team) - gfx_pretty_text_color(0.65f,1,0.65f,1); // team message + gfx_text_color(0.65f,1,0.65f,1); // team message - gfx_pretty_text(begin, y - 8 * (lines - 1), 8, chat_lines[r].text, 300); + gfx_text(0, begin, y - 8 * (lines - 1), 8, chat_lines[r].text, 300); y -= 6 * lines; } - gfx_pretty_text_color(1,1,1,1); + gfx_text_color(1,1,1,1); } // render goals @@ -2898,15 +2903,15 @@ void render_game() time = (client_tick()-gameobj->round_start_tick)/client_tickspeed(); sprintf(buf, "%d:%02d", time /60, time %60); - float w = gfx_pretty_text_width(16, buf, -1); - gfx_pretty_text(half-w/2, 2, 16, buf, -1); + float w = gfx_text_width(0, 16, buf, -1); + gfx_text(0, half-w/2, 2, 16, buf, -1); } if(gameobj->sudden_death) { const char *text = "Sudden Death"; - float w = gfx_pretty_text_width(16, text, -1); - gfx_pretty_text(half-w/2, 2, 16, text, -1); + float w = gfx_text_width(0, 16, text, -1); + gfx_text(0, half-w/2, 2, 16, text, -1); } // render small score hud @@ -2926,11 +2931,11 @@ void render_game() char buf[32]; sprintf(buf, "%d", gameobj->teamscore[t]); - float w = gfx_pretty_text_width(14, buf, -1); + float w = gfx_text_width(0, 14, buf, -1); if(gametype == GAMETYPE_CTF) { - gfx_pretty_text(whole-20-w/2+5, 300-40-15+t*20+2, 14, buf, -1); + gfx_text(0, whole-20-w/2+5, 300-40-15+t*20+2, 14, buf, -1); if(flags[t]) { if(flags[t]->carried_by == -2 || (flags[t]->carried_by == -1 && ((client_tick()/10)&1))) @@ -2950,8 +2955,8 @@ void render_game() { int id = flags[t]->carried_by%MAX_CLIENTS; const char *name = client_datas[id].name; - float w = gfx_pretty_text_width(10, name, -1); - gfx_pretty_text(whole-40-5-w, 300-40-15+t*20+2, 10, name, -1); + float w = gfx_text_width(0, 10, name, -1); + gfx_text(0, whole-40-5-w, 300-40-15+t*20+2, 10, name, -1); tee_render_info info = client_datas[id].render_info; info.size = 18.0f; @@ -2961,7 +2966,7 @@ void render_game() } } else - gfx_pretty_text(whole-20-w/2, 300-40-15+t*20+2, 14, buf, -1); + gfx_text(0, whole-20-w/2, 300-40-15+t*20+2, 14, buf, -1); } } @@ -2969,16 +2974,16 @@ void render_game() if(gameobj->warmup) { char buf[256]; - float w = gfx_pretty_text_width(24, "Warmup", -1); - gfx_pretty_text(150*gfx_screenaspect()+-w/2, 50, 24, "Warmup", -1); + float w = gfx_text_width(0, 24, "Warmup", -1); + gfx_text(0, 150*gfx_screenaspect()+-w/2, 50, 24, "Warmup", -1); int seconds = gameobj->warmup/SERVER_TICK_SPEED; if(seconds < 5) sprintf(buf, "%d.%d", seconds, (gameobj->warmup*10/SERVER_TICK_SPEED)%10); else sprintf(buf, "%d", seconds); - w = gfx_pretty_text_width(24, buf, -1); - gfx_pretty_text(150*gfx_screenaspect()+-w/2, 75, 24, buf, -1); + w = gfx_text_width(0, 24, buf, -1); + gfx_text(0, 150*gfx_screenaspect()+-w/2, 75, 24, buf, -1); } } @@ -3013,8 +3018,8 @@ void render_game() { gfx_mapscreen(0, 0, 300*gfx_screenaspect(), 300); const char *text = "Connection Problems..."; - float w = gfx_pretty_text_width(24, text, -1); - gfx_pretty_text(150*gfx_screenaspect()-w/2, 50, 24, text, -1); + float w = gfx_text_width(0, 24, text, -1); + gfx_text(0, 150*gfx_screenaspect()-w/2, 50, 24, text, -1); } if(config.debug && local_character && local_prev_character) @@ -3026,7 +3031,7 @@ void render_game() char buf[512]; sprintf(buf, "%f", speed); - gfx_pretty_text(150, 50, 24, buf, -1); + gfx_text(0, 150, 50, 24, buf, -1); } // render score board @@ -3055,8 +3060,8 @@ void render_game() else if(gameobj->teamscore[1] > gameobj->teamscore[0]) text = "Blue Team Wins!"; - float w = gfx_pretty_text_width(92.0f, text, -1); - gfx_pretty_text(width/2-w/2, 45, 92.0f, text, -1); + float w = gfx_text_width(0, 92.0f, text, -1); + gfx_text(0, width/2-w/2, 45, 92.0f, text, -1); } render_scoreboard(width/2-w-20, 150.0f, w, 0, "Red Team"); diff --git a/src/game/client/gc_menu.cpp b/src/game/client/gc_menu.cpp index 5062b15b..34558402 100644 --- a/src/game/client/gc_menu.cpp +++ b/src/game/client/gc_menu.cpp @@ -11,7 +11,6 @@ extern "C" { #include <engine/e_system.h> #include <engine/e_interface.h> #include <engine/e_config.h> - #include <engine/client/ec_ui.h> #include <engine/client/ec_font.h> } @@ -25,6 +24,7 @@ extern "C" { #include "../generated/gc_data.h" #include "gc_render.h" #include "gc_skin.h" +#include "gc_ui.h" #include <mastersrv/mastersrv.h> extern data_container *data; @@ -50,9 +50,6 @@ enum static int popup = POPUP_NONE; -//static vec4 gui_color(0.9f,0.78f,0.65f, 0.5f); -//static vec4 gui_color(0.78f,0.9f,0.65f, 0.5f); - static vec4 gui_color(0.65f,0.78f,0.9f, 0.5f); static vec4 color_tabbar_inactive_outgame(0,0,0,0.25f); @@ -62,290 +59,35 @@ static float color_ingame_scale_i = 0.5f; static float color_ingame_scale_a = 0.2f; static vec4 color_tabbar_inactive_ingame(gui_color.r*color_ingame_scale_i, gui_color.g*color_ingame_scale_i, gui_color.b*color_ingame_scale_i,0.75f); static vec4 color_tabbar_active_ingame(gui_color.r*color_ingame_scale_a, gui_color.g*color_ingame_scale_a, gui_color.b*color_ingame_scale_a,0.85f); -//static vec4 color_tabbar_inactive_ingame(0.2f,0.2f,0.2f,0.5f); -//static vec4 color_tabbar_active_ingame(0.2f,0.2f,0.2f,0.75f); static vec4 color_tabbar_inactive = color_tabbar_inactive_outgame; static vec4 color_tabbar_active = color_tabbar_active_outgame; enum { - /* - CORNER_TL=1, - CORNER_TR=2, - CORNER_BL=4, - CORNER_BR=8, - - CORNER_T=CORNER_TL|CORNER_TR, - CORNER_B=CORNER_BL|CORNER_BR, - CORNER_R=CORNER_TR|CORNER_BR, - CORNER_L=CORNER_TL|CORNER_BL, - - CORNER_ALL=CORNER_T|CORNER_B, - */ - PAGE_NEWS=0, PAGE_INTERNET, PAGE_LAN, PAGE_FAVORITES, PAGE_SETTINGS, - //PAGE_GAME, // not a real page PAGE_SYSTEM, }; -/* -typedef struct -{ - float x, y, w, h; -} RECT;*/ - -static RECT screen = { 0.0f, 0.0f, 848.0f, 480.0f }; extern void select_sprite(int id, int flags=0, int sx=0, int sy=0); -RECT *ui2_screen() -{ - float aspect = gfx_screenaspect(); - float w, h; - - h = 600; - w = aspect*h; - - screen.w = w; - screen.h = h; - - return &screen; -} - -void ui2_set_scale(float s) -{ - config.ui_scale = (int)(s*100.0f); -} - -float ui2_scale() -{ - return config.ui_scale/100.0f; -} - -void ui2_clip_enable(const RECT *r) -{ - float xscale = gfx_screenwidth()/ui2_screen()->w; - float yscale = gfx_screenheight()/ui2_screen()->h; - gfx_clip_enable((int)(r->x*xscale), (int)(r->y*yscale), (int)(r->w*xscale), (int)(r->h*yscale)); -} - -void ui2_clip_disable() -{ - gfx_clip_disable(); -} - -void ui2_hsplit_t(const RECT *original, float cut, RECT *top, RECT *bottom) -{ - RECT r = *original; - cut *= ui2_scale(); - - if (top) - { - top->x = r.x; - top->y = r.y; - top->w = r.w; - top->h = cut; - } - - if (bottom) - { - bottom->x = r.x; - bottom->y = r.y + cut; - bottom->w = r.w; - bottom->h = r.h - cut; - } -} - -void ui2_hsplit_b(const RECT *original, float cut, RECT *top, RECT *bottom) -{ - RECT r = *original; - cut *= ui2_scale(); - - if (top) - { - top->x = r.x; - top->y = r.y; - top->w = r.w; - top->h = r.h - cut; - } - - if (bottom) - { - bottom->x = r.x; - bottom->y = r.y + r.h - cut; - bottom->w = r.w; - bottom->h = cut; - } -} - - -void ui2_vsplit_mid(const RECT *original, RECT *left, RECT *right) -{ - RECT r = *original; - float cut = r.w/2; - - if (left) - { - left->x = r.x; - left->y = r.y; - left->w = cut; - left->h = r.h; - } - - if (right) - { - right->x = r.x + cut; - right->y = r.y; - right->w = r.w - cut; - right->h = r.h; - } -} - -void ui2_vsplit_l(const RECT *original, float cut, RECT *left, RECT *right) -{ - RECT r = *original; - cut *= ui2_scale(); - - if (left) - { - left->x = r.x; - left->y = r.y; - left->w = cut; - left->h = r.h; - } - - if (right) - { - right->x = r.x + cut; - right->y = r.y; - right->w = r.w - cut; - right->h = r.h; - } -} - -void ui2_vsplit_r(const RECT *original, float cut, RECT *left, RECT *right) -{ - RECT r = *original; - cut *= ui2_scale(); - - if (left) - { - left->x = r.x; - left->y = r.y; - left->w = r.w - cut; - left->h = r.h; - } - - if (right) - { - right->x = r.x + r.w - cut; - right->y = r.y; - right->w = cut; - right->h = r.h; - } -} - -void ui2_margin(const RECT *original, float cut, RECT *other_rect) -{ - RECT r = *original; - cut *= ui2_scale(); - - other_rect->x = r.x + cut; - other_rect->y = r.y + cut; - other_rect->w = r.w - 2*cut; - other_rect->h = r.h - 2*cut; -} - -void ui2_vmargin(const RECT *original, float cut, RECT *other_rect) -{ - RECT r = *original; - cut *= ui2_scale(); - - other_rect->x = r.x + cut; - other_rect->y = r.y; - other_rect->w = r.w - 2*cut; - other_rect->h = r.h; -} - -void ui2_hmargin(const RECT *original, float cut, RECT *other_rect) -{ - RECT r = *original; - cut *= ui2_scale(); - - other_rect->x = r.x; - other_rect->y = r.y + cut; - other_rect->w = r.w; - other_rect->h = r.h - 2*cut; -} - -typedef void (*ui2_draw_button_func)(const void *id, const char *text, int checked, const RECT *r, void *extra); - -int ui2_do_button(const void *id, const char *text, int checked, const RECT *r, ui2_draw_button_func draw_func, void *extra) -{ - /* logic */ - int ret = 0; - int inside = ui_mouse_inside(r); - - if(ui_active_item() == id) - { - if(!ui_mouse_button(0)) - { - if(inside) - ret = 1; - ui_set_active_item(0); - } - } - else if(ui_hot_item() == id) - { - if(ui_mouse_button(0)) - ui_set_active_item(id); - } - - if(inside) - ui_set_hot_item(id); - - if(draw_func) - draw_func(id, text, checked, r, extra); - return ret; -} - - -void ui2_do_label(const RECT *r, const char *text, float size, int align, int max_width = -1) -{ - gfx_blend_normal(); - size *= ui2_scale(); - if(align == 0) - { - float tw = gfx_pretty_text_width(size, text, max_width); - gfx_pretty_text(r->x + r->w/2-tw/2, r->y, size, text, max_width); - } - else if(align < 0) - gfx_pretty_text(r->x, r->y, size, text, max_width); - else if(align > 0) - { - float tw = gfx_pretty_text_width(size, text, max_width); - gfx_pretty_text(r->x + r->w-tw, r->y, size, text, max_width); - } -} - - extern void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners); extern void draw_round_rect(float x, float y, float w, float h, float r); -static void ui2_draw_rect(const RECT *r, vec4 color, int corners, float rounding) +static void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding) { gfx_texture_set(-1); gfx_quads_begin(); gfx_setcolor(color.r, color.g, color.b, color.a); - draw_round_rect_ext(r->x,r->y,r->w,r->h,rounding*ui2_scale(), corners); + draw_round_rect_ext(r->x,r->y,r->w,r->h,rounding*ui_scale(), corners); gfx_quads_end(); } -static void ui2_draw_browse_icon(int what, const RECT *r) +static void ui_draw_browse_icon(int what, const RECT *r) { gfx_texture_set(data->images[IMAGE_BROWSEICONS].id); gfx_quads_begin(); @@ -368,100 +110,88 @@ static void ui2_draw_browse_icon(int what, const RECT *r) gfx_quads_end(); } -static void ui2_draw_menu_button(const void *id, const char *text, int checked, const RECT *r, void *extra) +static void ui_draw_menu_button(const void *id, const char *text, int checked, const RECT *r, const void *extra) { - ui2_draw_rect(r, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f); - ui2_do_label(r, text, 18.0f, 0); + ui_draw_rect(r, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f); + ui_do_label(r, text, 18.0f, 0); } -static void ui2_draw_keyselect_button(const void *id, const char *text, int checked, const RECT *r, void *extra) +static void ui_draw_keyselect_button(const void *id, const char *text, int checked, const RECT *r, const void *extra) { - ui2_draw_rect(r, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f); - ui2_do_label(r, text, 14.0f, 0); + ui_draw_rect(r, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f); + ui_do_label(r, text, 14.0f, 0); } -static void ui2_draw_menu_tab_button(const void *id, const char *text, int checked, const RECT *r, void *extra) +static void ui_draw_menu_tab_button(const void *id, const char *text, int checked, const RECT *r, const void *extra) { if(checked) - ui2_draw_rect(r, color_tabbar_active, CORNER_T, 10.0f); + ui_draw_rect(r, color_tabbar_active, CORNER_T, 10.0f); else - ui2_draw_rect(r, color_tabbar_inactive, CORNER_T, 10.0f); - ui2_do_label(r, text, 22.0f, 0); + ui_draw_rect(r, color_tabbar_inactive, CORNER_T, 10.0f); + ui_do_label(r, text, 22.0f, 0); } -static void ui2_draw_settings_tab_button(const void *id, const char *text, int checked, const RECT *r, void *extra) +static void ui_draw_settings_tab_button(const void *id, const char *text, int checked, const RECT *r, const void *extra) { if(checked) - ui2_draw_rect(r, color_tabbar_active, CORNER_R, 10.0f); + ui_draw_rect(r, color_tabbar_active, CORNER_R, 10.0f); else - ui2_draw_rect(r, color_tabbar_inactive, CORNER_R, 10.0f); - ui2_do_label(r, text, 20.0f, 0); + ui_draw_rect(r, color_tabbar_inactive, CORNER_R, 10.0f); + ui_do_label(r, text, 20.0f, 0); } -static void ui2_draw_grid_header(const void *id, const char *text, int checked, const RECT *r, void *extra) +static void ui_draw_grid_header(const void *id, const char *text, int checked, const RECT *r, const void *extra) { if(checked) - ui2_draw_rect(r, vec4(1,1,1,0.5f), CORNER_T, 5.0f); - //else - // ui2_draw_rect(r, vec4(1,1,1,0.1f), CORNER_T, 5.0f); + ui_draw_rect(r, vec4(1,1,1,0.5f), CORNER_T, 5.0f); RECT t; - ui2_vsplit_l(r, 5.0f, 0, &t); - ui2_do_label(&t, text, 14.0f, -1); -} -/* -static void ui2_draw_grid_cell_l(const void *id, const char *text, int checked, const RECT *r, void *extra) -{ - ui2_do_label(r, text, 18, -1); + ui_vsplit_l(r, 5.0f, 0, &t); + ui_do_label(&t, text, 14.0f, -1); } -static void ui2_draw_grid_cell_r(const void *id, const char *text, int checked, const RECT *r, void *extra) -{ - ui2_do_label(r, text, 18, 1); -}*/ - -static void ui2_draw_list_row(const void *id, const char *text, int checked, const RECT *r, void *extra) +static void ui_draw_list_row(const void *id, const char *text, int checked, const RECT *r, const void *extra) { if(checked) { RECT sr = *r; - ui2_margin(&sr, 1.5f, &sr); - ui2_draw_rect(&sr, vec4(1,1,1,0.5f), CORNER_ALL, 4.0f); + ui_margin(&sr, 1.5f, &sr); + ui_draw_rect(&sr, vec4(1,1,1,0.5f), CORNER_ALL, 4.0f); } - ui2_do_label(r, text, 14.0f, -1); + ui_do_label(r, text, 14.0f, -1); } -static void ui2_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const RECT *r) +static void ui_draw_checkbox_common(const void *id, const char *text, const char *boxtext, const RECT *r) { RECT c = *r; RECT t = *r; c.w = c.h; t.x += c.w; t.w -= c.w; - ui2_vsplit_l(&t, 5.0f, 0, &t); + ui_vsplit_l(&t, 5.0f, 0, &t); - ui2_margin(&c, 2.0f, &c); - ui2_draw_rect(&c, vec4(1,1,1,0.25f), CORNER_ALL, 3.0f); + ui_margin(&c, 2.0f, &c); + ui_draw_rect(&c, vec4(1,1,1,0.25f), CORNER_ALL, 3.0f); c.y += 2; - ui2_do_label(&c, boxtext, 12.0f, 0); - ui2_do_label(&t, text, 14.0f, -1); + ui_do_label(&c, boxtext, 12.0f, 0); + ui_do_label(&t, text, 14.0f, -1); } -static void ui2_draw_checkbox(const void *id, const char *text, int checked, const RECT *r, void *extra) +static void ui_draw_checkbox(const void *id, const char *text, int checked, const RECT *r, const void *extra) { - ui2_draw_checkbox_common(id, text, checked?"X":"", r); + ui_draw_checkbox_common(id, text, checked?"X":"", r); } -static void ui2_draw_checkbox_number(const void *id, const char *text, int checked, const RECT *r, void *extra) +static void ui_draw_checkbox_number(const void *id, const char *text, int checked, const RECT *r, const void *extra) { char buf[16]; sprintf(buf, "%d", checked); - ui2_draw_checkbox_common(id, text, buf, r); + ui_draw_checkbox_common(id, text, buf, r); } -int ui2_do_edit_box(void *id, const RECT *rect, char *str, int str_size, bool hidden=false) +int ui_do_edit_box(void *id, const RECT *rect, char *str, int str_size, bool hidden=false) { int inside = ui_mouse_inside(rect); int r = 0; @@ -477,7 +207,7 @@ int ui2_do_edit_box(void *id, const RECT *rect, char *str, int str_size, bool hi for (int i = 1; i <= len; i++) { - if (gfx_pretty_text_width(14.0f, str, i) + 10 > mx_rel) + if (gfx_text_width(0, 14.0f, str, i) + 10 > mx_rel) { at_index = i - 1; break; @@ -556,8 +286,8 @@ int ui2_do_edit_box(void *id, const RECT *rect, char *str, int str_size, bool hi ui_set_hot_item(id); RECT textbox = *rect; - ui2_draw_rect(&textbox, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f); - ui2_vmargin(&textbox, 5.0f, &textbox); + ui_draw_rect(&textbox, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f); + ui_vmargin(&textbox, 5.0f, &textbox); const char *display_str = str; char stars[128]; @@ -572,23 +302,23 @@ int ui2_do_edit_box(void *id, const RECT *rect, char *str, int str_size, bool hi display_str = stars; } - ui2_do_label(&textbox, display_str, 14, -1); + ui_do_label(&textbox, display_str, 14, -1); if (ui_last_active_item() == id && !just_got_active) { - float w = gfx_pretty_text_width(14.0f, display_str, at_index); - textbox.x += w*ui2_scale(); - ui2_do_label(&textbox, "_", 14, -1); + float w = gfx_text_width(0, 14.0f, display_str, at_index); + textbox.x += w*ui_scale(); + ui_do_label(&textbox, "_", 14, -1); } return r; } -float ui2_do_scrollbar_v(const void *id, const RECT *rect, float current) +float ui_do_scrollbar_v(const void *id, const RECT *rect, float current) { RECT handle; static float offset_y; - ui2_hsplit_t(rect, 33, &handle, 0); + ui_hsplit_t(rect, 33, &handle, 0); handle.y += (rect->h-handle.h)*current; @@ -622,29 +352,29 @@ float ui2_do_scrollbar_v(const void *id, const RECT *rect, float current) // render RECT rail; - ui2_vmargin(rect, 5.0f, &rail); - ui2_draw_rect(&rail, vec4(1,1,1,0.25f), 0, 0.0f); + ui_vmargin(rect, 5.0f, &rail); + ui_draw_rect(&rail, vec4(1,1,1,0.25f), 0, 0.0f); RECT slider = handle; slider.w = rail.x-slider.x; - ui2_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_L, 2.5f); + ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_L, 2.5f); slider.x = rail.x+rail.w; - ui2_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_R, 2.5f); + ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_R, 2.5f); slider = handle; - ui2_margin(&slider, 5.0f, &slider); - ui2_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_ALL, 2.5f); + ui_margin(&slider, 5.0f, &slider); + ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_ALL, 2.5f); return ret; } -float ui2_do_scrollbar_h(const void *id, const RECT *rect, float current) +float ui_do_scrollbar_h(const void *id, const RECT *rect, float current) { RECT handle; static float offset_x; - ui2_vsplit_l(rect, 33, &handle, 0); + ui_vsplit_l(rect, 33, &handle, 0); handle.x += (rect->w-handle.w)*current; @@ -678,23 +408,23 @@ float ui2_do_scrollbar_h(const void *id, const RECT *rect, float current) // render RECT rail; - ui2_hmargin(rect, 5.0f, &rail); - ui2_draw_rect(&rail, vec4(1,1,1,0.25f), 0, 0.0f); + ui_hmargin(rect, 5.0f, &rail); + ui_draw_rect(&rail, vec4(1,1,1,0.25f), 0, 0.0f); RECT slider = handle; slider.h = rail.y-slider.y; - ui2_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_T, 2.5f); + ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_T, 2.5f); slider.y = rail.y+rail.h; - ui2_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_B, 2.5f); + ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_B, 2.5f); slider = handle; - ui2_margin(&slider, 5.0f, &slider); - ui2_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_ALL, 2.5f); + ui_margin(&slider, 5.0f, &slider); + ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_ALL, 2.5f); return ret; } -int ui2_do_key_reader(void *id, const RECT *rect, int key) +int ui_do_key_reader(void *id, const RECT *rect, int key) { // process static bool mouse_released = true; @@ -730,9 +460,9 @@ int ui2_do_key_reader(void *id, const RECT *rect, int key) // draw if (ui_active_item() == id) - ui2_draw_keyselect_button(id, "???", 0, rect, 0); + ui_draw_keyselect_button(id, "???", 0, rect, 0); else - ui2_draw_keyselect_button(id, inp_key_name(key), 0, rect, 0); + ui_draw_keyselect_button(id, inp_key_name(key), 0, rect, 0); return new_key; } @@ -751,35 +481,35 @@ static int menu2_render_menubar(RECT r) { if(0) // this is not done yet { - ui2_vsplit_l(&box, 90.0f, &button, &box); + ui_vsplit_l(&box, 90.0f, &button, &box); static int news_button=0; - if (ui2_do_button(&news_button, "News", active_page==PAGE_NEWS, &button, ui2_draw_menu_tab_button, 0)) + if (ui_do_button(&news_button, "News", active_page==PAGE_NEWS, &button, ui_draw_menu_tab_button, 0)) new_page = PAGE_NEWS; - ui2_vsplit_l(&box, 30.0f, 0, &box); + ui_vsplit_l(&box, 30.0f, 0, &box); } } else { - ui2_vsplit_l(&box, 90.0f, &button, &box); + ui_vsplit_l(&box, 90.0f, &button, &box); static int game_button=0; - if (ui2_do_button(&game_button, "Game", menu_game_active, &button, ui2_draw_menu_tab_button, 0)) + if (ui_do_button(&game_button, "Game", menu_game_active, &button, ui_draw_menu_tab_button, 0)) menu_game_active = true; - ui2_vsplit_l(&box, 30.0f, 0, &box); + ui_vsplit_l(&box, 30.0f, 0, &box); } - ui2_vsplit_l(&box, 110.0f, &button, &box); + ui_vsplit_l(&box, 110.0f, &button, &box); static int internet_button=0; - if (ui2_do_button(&internet_button, "Internet", active_page==PAGE_INTERNET, &button, ui2_draw_menu_tab_button, 0)) + if (ui_do_button(&internet_button, "Internet", active_page==PAGE_INTERNET, &button, ui_draw_menu_tab_button, 0)) { client_serverbrowse_refresh(0); new_page = PAGE_INTERNET; } - ui2_vsplit_l(&box, 4.0f, 0, &box); - ui2_vsplit_l(&box, 90.0f, &button, &box); + ui_vsplit_l(&box, 4.0f, 0, &box); + ui_vsplit_l(&box, 90.0f, &button, &box); static int lan_button=0; - if (ui2_do_button(&lan_button, "LAN", active_page==PAGE_LAN, &button, ui2_draw_menu_tab_button, 0)) + if (ui_do_button(&lan_button, "LAN", active_page==PAGE_LAN, &button, ui_draw_menu_tab_button, 0)) { client_serverbrowse_refresh(1); new_page = PAGE_LAN; @@ -787,31 +517,31 @@ static int menu2_render_menubar(RECT r) if(0) // this one is not done yet { - ui2_vsplit_l(&box, 4.0f, 0, &box); - ui2_vsplit_l(&box, 120.0f, &button, &box); + ui_vsplit_l(&box, 4.0f, 0, &box); + ui_vsplit_l(&box, 120.0f, &button, &box); static int favorites_button=0; - if (ui2_do_button(&favorites_button, "Favorites", active_page==PAGE_FAVORITES, &button, ui2_draw_menu_tab_button, 0)) + if (ui_do_button(&favorites_button, "Favorites", active_page==PAGE_FAVORITES, &button, ui_draw_menu_tab_button, 0)) new_page = PAGE_FAVORITES; } /* - ui2_vsplit_r(&box, 110.0f, &box, &button); + ui_vsplit_r(&box, 110.0f, &box, &button); static int system_button=0; - if (ui2_do_button(&system_button, "System", config.ui_page==PAGE_SYSTEM, &button, ui2_draw_menu_tab_button, 0)) + if (ui_do_button(&system_button, "System", config.ui_page==PAGE_SYSTEM, &button, ui_draw_menu_tab_button, 0)) config.ui_page = PAGE_SYSTEM; - ui2_vsplit_r(&box, 30.0f, &box, 0); + ui_vsplit_r(&box, 30.0f, &box, 0); */ - ui2_vsplit_r(&box, 110.0f, &box, &button); + ui_vsplit_r(&box, 110.0f, &box, &button); static int quit_button=0; - if (ui2_do_button(&quit_button, "Quit", 0, &button, ui2_draw_menu_tab_button, 0)) + if (ui_do_button(&quit_button, "Quit", 0, &button, ui_draw_menu_tab_button, 0)) popup = POPUP_QUIT; - ui2_vsplit_r(&box, 10.0f, &box, &button); - ui2_vsplit_r(&box, 110.0f, &box, &button); + ui_vsplit_r(&box, 10.0f, &box, &button); + ui_vsplit_r(&box, 110.0f, &box, &button); static int settings_button=0; - if (ui2_do_button(&settings_button, "Settings", active_page==PAGE_SETTINGS, &button, ui2_draw_menu_tab_button, 0)) + if (ui_do_button(&settings_button, "Settings", active_page==PAGE_SETTINGS, &button, ui_draw_menu_tab_button, 0)) new_page = PAGE_SETTINGS; if(new_page != -1) @@ -825,7 +555,7 @@ static int menu2_render_menubar(RECT r) static void menu2_render_background() { - RECT s = *ui2_screen(); + RECT s = *ui_screen(); gfx_texture_set(-1); gfx_quads_begin(); @@ -853,28 +583,11 @@ extern "C" void *gfx_font_set; void render_loading(float percent) { - if (1) - { - static FONT_SET font_set; - static bool first = true; - - gfx_font_set = &font_set; - - if (first) - { - int before = gfx_memory_usage(); - font_set_load(&font_set, "fonts/default_font%d.tfnt", "fonts/default_font%d.png", "fonts/default_font%d_b.png", 14, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 36); - first = false; - int after = gfx_memory_usage(); - dbg_msg("font", "gfx memory usage: %d", after-before); - } - } - // need up date this here to get correct vec3 rgb = hsl_to_rgb(vec3(config.ui_color_hue/255.0f, config.ui_color_sat/255.0f, config.ui_color_lht/255.0f)); gui_color = vec4(rgb.r, rgb.g, rgb.b, config.ui_color_alpha/255.0f); - RECT screen = *ui2_screen(); + RECT screen = *ui_screen(); gfx_mapscreen(screen.x, screen.y, screen.w, screen.h); menu2_render_background(); @@ -896,7 +609,7 @@ void render_loading(float percent) const char *caption = "Loading"; - tw = gfx_pretty_text_width(48.0f, caption, -1); + tw = gfx_text_width(0, 48.0f, caption, -1); RECT r; r.x = x+w/2; r.y = y+20; @@ -913,10 +626,10 @@ void render_loading(float percent) static void menu2_render_serverbrowser(RECT main_view) { - ui2_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f); + ui_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f); RECT view; - ui2_margin(&main_view, 10.0f, &view); + ui_margin(&main_view, 10.0f, &view); RECT headers; RECT filters; @@ -925,27 +638,27 @@ static void menu2_render_serverbrowser(RECT main_view) RECT server_details; RECT server_scoreboard; - //ui2_hsplit_t(&view, 20.0f, &status, &view); - ui2_hsplit_b(&view, 110.0f, &view, &filters); + //ui_hsplit_t(&view, 20.0f, &status, &view); + ui_hsplit_b(&view, 110.0f, &view, &filters); // split off a piece for details and scoreboard - ui2_vsplit_r(&view, 200.0f, &view, &server_details); + ui_vsplit_r(&view, 200.0f, &view, &server_details); // server list - ui2_hsplit_t(&view, 20.0f, &headers, &view); - //ui2_hsplit_b(&view, 110.0f, &view, &filters); - ui2_hsplit_b(&view, 5.0f, &view, 0); - ui2_hsplit_b(&view, 20.0f, &view, &status); + ui_hsplit_t(&view, 20.0f, &headers, &view); + //ui_hsplit_b(&view, 110.0f, &view, &filters); + ui_hsplit_b(&view, 5.0f, &view, 0); + ui_hsplit_b(&view, 20.0f, &view, &status); - //ui2_vsplit_r(&filters, 300.0f, &filters, &toolbox); - //ui2_vsplit_r(&filters, 150.0f, &filters, 0); + //ui_vsplit_r(&filters, 300.0f, &filters, &toolbox); + //ui_vsplit_r(&filters, 150.0f, &filters, 0); - ui2_vsplit_mid(&filters, &filters, &toolbox); - ui2_vsplit_r(&filters, 50.0f, &filters, 0); + ui_vsplit_mid(&filters, &filters, &toolbox); + ui_vsplit_r(&filters, 50.0f, &filters, 0); // split of the scrollbar - ui2_draw_rect(&headers, vec4(1,1,1,0.25f), CORNER_T, 5.0f); - ui2_vsplit_r(&headers, 20.0f, &headers, 0); + ui_draw_rect(&headers, vec4(1,1,1,0.25f), CORNER_T, 5.0f); + ui_vsplit_r(&headers, 20.0f, &headers, 0); struct column { @@ -995,12 +708,12 @@ static void menu2_render_serverbrowser(RECT main_view) { if(cols[i].direction == -1) { - ui2_vsplit_l(&headers, cols[i].width, &cols[i].rect, &headers); + ui_vsplit_l(&headers, cols[i].width, &cols[i].rect, &headers); if(i+1 < num_cols) { //cols[i].flags |= SPACER; - ui2_vsplit_l(&headers, 2, &cols[i].spacer, &headers); + ui_vsplit_l(&headers, 2, &cols[i].spacer, &headers); } } } @@ -1009,8 +722,8 @@ static void menu2_render_serverbrowser(RECT main_view) { if(cols[i].direction == 1) { - ui2_vsplit_r(&headers, cols[i].width, &headers, &cols[i].rect); - ui2_vsplit_r(&headers, 2, &headers, &cols[i].spacer); + ui_vsplit_r(&headers, cols[i].width, &headers, &cols[i].rect); + ui_vsplit_r(&headers, 2, &headers, &cols[i].spacer); } } @@ -1023,7 +736,7 @@ static void menu2_render_serverbrowser(RECT main_view) // do headers for(int i = 0; i < num_cols; i++) { - if(ui2_do_button(cols[i].caption, cols[i].caption, config.b_sort == cols[i].sort, &cols[i].rect, ui2_draw_grid_header, 0)) + if(ui_do_button(cols[i].caption, cols[i].caption, config.b_sort == cols[i].sort, &cols[i].rect, ui_draw_grid_header, 0)) { if(cols[i].sort != -1) { @@ -1036,10 +749,10 @@ static void menu2_render_serverbrowser(RECT main_view) } } - ui2_draw_rect(&view, vec4(0,0,0,0.15f), 0, 0); + ui_draw_rect(&view, vec4(0,0,0,0.15f), 0, 0); RECT scroll; - ui2_vsplit_r(&view, 15, &view, &scroll); + ui_vsplit_r(&view, 15, &view, &scroll); int num_servers = client_serverbrowse_sorted_num(); @@ -1047,8 +760,8 @@ static void menu2_render_serverbrowser(RECT main_view) static int scrollbar = 0; static float scrollvalue = 0; //static int selected_index = -1; - ui2_hmargin(&scroll, 5.0f, &scroll); - scrollvalue = ui2_do_scrollbar_v(&scrollbar, &scroll, scrollvalue); + ui_hmargin(&scroll, 5.0f, &scroll); + scrollvalue = ui_do_scrollbar_v(&scrollbar, &scroll, scrollvalue); int scrollnum = num_servers-num+10; if(scrollnum > 0) @@ -1065,7 +778,7 @@ static void menu2_render_serverbrowser(RECT main_view) scrollnum = 0; // set clipping - ui2_clip_enable(&view); + ui_clip_enable(&view); int start = (int)(scrollnum*scrollvalue); if(start < 0) @@ -1094,16 +807,16 @@ static void menu2_render_serverbrowser(RECT main_view) RECT whole; int h = (item->num_players+2)/3; - ui2_hsplit_t(&view, 25.0f+h*15.0f, &whole, &view); + ui_hsplit_t(&view, 25.0f+h*15.0f, &whole, &view); select_hit_box = whole; RECT r = whole; - ui2_margin(&r, 1.5f, &r); - ui2_draw_rect(&r, vec4(1,1,1,0.5f), CORNER_ALL, 4.0f); + ui_margin(&r, 1.5f, &r); + ui_draw_rect(&r, vec4(1,1,1,0.5f), CORNER_ALL, 4.0f); - ui2_hsplit_t(&whole, 20.0f, &row, &whole); - ui2_vsplit_l(&whole, 50.0f, 0, &whole); + ui_hsplit_t(&whole, 20.0f, &row, &whole); + ui_vsplit_l(&whole, 50.0f, 0, &whole); for(int p = 0; p < item->num_players; p+=3) @@ -1112,20 +825,20 @@ static void menu2_render_serverbrowser(RECT main_view) RECT player_rect; RECT player_score; RECT player_name; - ui2_hsplit_t(&whole, 15.0f, &player_row, &whole); + ui_hsplit_t(&whole, 15.0f, &player_row, &whole); for(int a = 0; a < 3; a++) { if(p+a >= item->num_players) break; - ui2_vsplit_l(&player_row, 170.0f, &player_rect, &player_row); - ui2_vsplit_l(&player_rect, 30.0f, &player_score, &player_name); - ui2_vsplit_l(&player_name, 10.0f, 0, &player_name); + ui_vsplit_l(&player_row, 170.0f, &player_rect, &player_row); + ui_vsplit_l(&player_rect, 30.0f, &player_score, &player_name); + ui_vsplit_l(&player_name, 10.0f, 0, &player_name); char buf[32]; sprintf(buf, "%d", item->player_scores[p+a]); - ui2_do_label(&player_score, buf, 12.0f, 1); - ui2_do_label(&player_name, item->player_names[p+a], 12.0f, -1); + ui_do_label(&player_score, buf, 12.0f, 1); + ui_do_label(&player_name, item->player_names[p+a], 12.0f, -1); } } @@ -1133,7 +846,7 @@ static void menu2_render_serverbrowser(RECT main_view) } else { - ui2_hsplit_t(&view, 20.0f, &row, &view); + ui_hsplit_t(&view, 20.0f, &row, &view); select_hit_box = row; } @@ -1146,7 +859,7 @@ static void menu2_render_serverbrowser(RECT main_view) select_hit_box.y = original_view.y; } - if(ui2_do_button(item, "", selected, &select_hit_box, 0, 0)) + if(ui_do_button(item, "", selected, &select_hit_box, 0, 0)) { new_selected = item_index; } @@ -1168,39 +881,39 @@ static void menu2_render_serverbrowser(RECT main_view) //int s = 0; int id = cols[c].id; - //s = ui2_do_button(item, "L", l, &button, ui2_draw_browse_icon, 0); + //s = ui_do_button(item, "L", l, &button, ui_draw_browse_icon, 0); if(id == COL_FLAGS) { if(item->flags&1) - ui2_draw_browse_icon(0x100, &button); + ui_draw_browse_icon(0x100, &button); } else if(id == COL_NAME) - ui2_do_label(&button, item->name, 15.0f, -1); + ui_do_label(&button, item->name, 15.0f, -1); else if(id == COL_MAP) - ui2_do_label(&button, item->map, 15.0f, -1); + ui_do_label(&button, item->map, 15.0f, -1); else if(id == COL_PLAYERS) { sprintf(temp, "%i/%i", item->num_players, item->max_players); - ui2_do_label(&button, temp, 15.0f, 1); + ui_do_label(&button, temp, 15.0f, 1); } else if(id == COL_PING) { sprintf(temp, "%i", item->latency); - ui2_do_label(&button, temp, 15.0f, 1); + ui_do_label(&button, temp, 15.0f, 1); } else if(id == COL_PROGRESS) { if(item->progression > 100) item->progression = 100; - ui2_draw_browse_icon(item->progression, &button); + ui_draw_browse_icon(item->progression, &button); } else if(id == COL_VERSION) { const char *version = item->version; if(strcmp(version, "0.3 e2d7973c6647a13c") == 0) // TODO: remove me later on version = "0.3.0"; - ui2_do_label(&button, version, 15.0f, 1); + ui_do_label(&button, version, 15.0f, 1); } else if(id == COL_GAMETYPE) { @@ -1208,12 +921,12 @@ static void menu2_render_serverbrowser(RECT main_view) if(item->game_type == GAMETYPE_DM) type = "DM"; else if(item->game_type == GAMETYPE_TDM) type = "TDM"; else if(item->game_type == GAMETYPE_CTF) type = "CTF"; - ui2_do_label(&button, type, 15.0f, 0); + ui_do_label(&button, type, 15.0f, 0); } } } - ui2_clip_disable(); + ui_clip_disable(); if(new_selected != -1) { @@ -1227,22 +940,22 @@ static void menu2_render_serverbrowser(RECT main_view) SERVER_INFO *selected_server = client_serverbrowse_sorted_get(selected_index); RECT server_header; - ui2_vsplit_l(&server_details, 10.0f, 0x0, &server_details); + ui_vsplit_l(&server_details, 10.0f, 0x0, &server_details); // split off a piece to use for scoreboard - ui2_hsplit_t(&server_details, 140.0f, &server_details, &server_scoreboard); - ui2_hsplit_b(&server_details, 10.0f, &server_details, 0x0); + ui_hsplit_t(&server_details, 140.0f, &server_details, &server_scoreboard); + ui_hsplit_b(&server_details, 10.0f, &server_details, 0x0); // server details - ui2_hsplit_t(&server_details, 20.0f, &server_header, &server_details); - ui2_draw_rect(&server_header, vec4(1,1,1,0.25f), CORNER_T, 4.0f); - ui2_draw_rect(&server_details, vec4(0,0,0,0.15f), CORNER_B, 4.0f); - ui2_vsplit_l(&server_header, 8.0f, 0x0, &server_header); - ui2_do_label(&server_header, "Server Details: ", 14.0f, -1); + ui_hsplit_t(&server_details, 20.0f, &server_header, &server_details); + ui_draw_rect(&server_header, vec4(1,1,1,0.25f), CORNER_T, 4.0f); + ui_draw_rect(&server_details, vec4(0,0,0,0.15f), CORNER_B, 4.0f); + ui_vsplit_l(&server_header, 8.0f, 0x0, &server_header); + ui_do_label(&server_header, "Server Details: ", 14.0f, -1); - ui2_vsplit_l(&server_details, 5.0f, 0x0, &server_details); + ui_vsplit_l(&server_details, 5.0f, 0x0, &server_details); - ui2_margin(&server_details, 3.0f, &server_details); + ui_margin(&server_details, 3.0f, &server_details); if (selected_server) { @@ -1250,32 +963,32 @@ static void menu2_render_serverbrowser(RECT main_view) RECT row; static char *labels[] = { "Version:", "Game Type:", "Progression:", "Ping:" }; - ui2_hsplit_t(&server_details, row_height, &row, &server_details); - ui2_do_label(&row, selected_server->name, 15.0f, -1); + ui_hsplit_t(&server_details, row_height, &row, &server_details); + ui_do_label(&row, selected_server->name, 15.0f, -1); - ui2_hsplit_t(&server_details, row_height, &row, &server_details); - ui2_vsplit_l(&row, 1.0f, 0x0, &row); - ui2_do_label(&row, selected_server->address, 14.0f, -1); + ui_hsplit_t(&server_details, row_height, &row, &server_details); + ui_vsplit_l(&row, 1.0f, 0x0, &row); + ui_do_label(&row, selected_server->address, 14.0f, -1); RECT left_column; RECT right_column; - ui2_vsplit_l(&server_details, 5.0f, 0x0, &server_details); - ui2_vsplit_l(&server_details, 80.0f, &left_column, &right_column); + ui_vsplit_l(&server_details, 5.0f, 0x0, &server_details); + ui_vsplit_l(&server_details, 80.0f, &left_column, &right_column); for (int i = 0; i < 4; i++) { - ui2_hsplit_t(&left_column, 15.0f, &row, &left_column); - ui2_do_label(&row, labels[i], 13.0f, -1); + ui_hsplit_t(&left_column, 15.0f, &row, &left_column); + ui_do_label(&row, labels[i], 13.0f, -1); } - ui2_hsplit_t(&right_column, 15.0f, &row, &right_column); - ui2_do_label(&row, selected_server->version, 13.0f, -1); + ui_hsplit_t(&right_column, 15.0f, &row, &right_column); + ui_do_label(&row, selected_server->version, 13.0f, -1); - ui2_hsplit_t(&right_column, 15.0f, &row, &right_column); + ui_hsplit_t(&right_column, 15.0f, &row, &right_column); static char *game_types[] = { "DM", "TDM", "CTF" }; if (selected_server->game_type >= 0 && selected_server->game_type < (int)(sizeof(game_types)/sizeof(*game_types))) - ui2_do_label(&row, game_types[selected_server->game_type], 13.0f, -1); + ui_do_label(&row, game_types[selected_server->game_type], 13.0f, -1); char temp[16]; @@ -1283,25 +996,25 @@ static void menu2_render_serverbrowser(RECT main_view) sprintf(temp, "N/A"); else sprintf(temp, "%d%%", selected_server->progression); - ui2_hsplit_t(&right_column, 15.0f, &row, &right_column); - ui2_do_label(&row, temp, 13.0f, -1); + ui_hsplit_t(&right_column, 15.0f, &row, &right_column); + ui_do_label(&row, temp, 13.0f, -1); sprintf(temp, "%d", selected_server->latency); - ui2_hsplit_t(&right_column, 15.0f, &row, &right_column); - ui2_do_label(&row, temp, 13.0f, -1); + ui_hsplit_t(&right_column, 15.0f, &row, &right_column); + ui_do_label(&row, temp, 13.0f, -1); } // server scoreboard - ui2_hsplit_b(&server_scoreboard, 10.0f, &server_scoreboard, 0x0); - ui2_hsplit_t(&server_scoreboard, 20.0f, &server_header, &server_scoreboard); - ui2_draw_rect(&server_header, vec4(1,1,1,0.25f), CORNER_T, 4.0f); - ui2_draw_rect(&server_scoreboard, vec4(0,0,0,0.15f), CORNER_B, 4.0f); - ui2_vsplit_l(&server_header, 8.0f, 0x0, &server_header); - ui2_do_label(&server_header, "Scoreboard: ", 14.0f, -1); + ui_hsplit_b(&server_scoreboard, 10.0f, &server_scoreboard, 0x0); + ui_hsplit_t(&server_scoreboard, 20.0f, &server_header, &server_scoreboard); + ui_draw_rect(&server_header, vec4(1,1,1,0.25f), CORNER_T, 4.0f); + ui_draw_rect(&server_scoreboard, vec4(0,0,0,0.15f), CORNER_B, 4.0f); + ui_vsplit_l(&server_header, 8.0f, 0x0, &server_header); + ui_do_label(&server_header, "Scoreboard: ", 14.0f, -1); - ui2_vsplit_l(&server_scoreboard, 5.0f, 0x0, &server_scoreboard); + ui_vsplit_l(&server_scoreboard, 5.0f, 0x0, &server_scoreboard); - ui2_margin(&server_scoreboard, 3.0f, &server_scoreboard); + ui_margin(&server_scoreboard, 3.0f, &server_scoreboard); if (selected_server) { @@ -1309,88 +1022,88 @@ static void menu2_render_serverbrowser(RECT main_view) { RECT row; char temp[16]; - ui2_hsplit_t(&server_scoreboard, 16.0f, &row, &server_scoreboard); + ui_hsplit_t(&server_scoreboard, 16.0f, &row, &server_scoreboard); sprintf(temp, "%d", selected_server->player_scores[i]); - ui2_do_label(&row, temp, 14.0f, -1); + ui_do_label(&row, temp, 14.0f, -1); - ui2_vsplit_l(&row, 25.0f, 0x0, &row); - ui2_do_label(&row, selected_server->player_names[i], 14.0f, -1); + ui_vsplit_l(&row, 25.0f, 0x0, &row); + ui_do_label(&row, selected_server->player_names[i], 14.0f, -1); } } RECT button; RECT types; - ui2_hsplit_t(&filters, 20.0f, &button, &filters); - ui2_do_label(&button, "Quick search: ", 14.0f, -1); - ui2_vsplit_l(&button, 95.0f, 0, &button); - ui2_do_edit_box(&config.b_filter_string, &button, config.b_filter_string, sizeof(config.b_filter_string)); + ui_hsplit_t(&filters, 20.0f, &button, &filters); + ui_do_label(&button, "Quick search: ", 14.0f, -1); + ui_vsplit_l(&button, 95.0f, 0, &button); + ui_do_edit_box(&config.b_filter_string, &button, config.b_filter_string, sizeof(config.b_filter_string)); - ui2_vsplit_l(&filters, 180.0f, &filters, &types); + ui_vsplit_l(&filters, 180.0f, &filters, &types); // render filters - ui2_hsplit_t(&filters, 20.0f, &button, &filters); - if (ui2_do_button(&config.b_filter_empty, "Has people playing", config.b_filter_empty, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&filters, 20.0f, &button, &filters); + if (ui_do_button(&config.b_filter_empty, "Has people playing", config.b_filter_empty, &button, ui_draw_checkbox, 0)) config.b_filter_empty ^= 1; - ui2_hsplit_t(&filters, 20.0f, &button, &filters); - if (ui2_do_button(&config.b_filter_full, "Server not full", config.b_filter_full, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&filters, 20.0f, &button, &filters); + if (ui_do_button(&config.b_filter_full, "Server not full", config.b_filter_full, &button, ui_draw_checkbox, 0)) config.b_filter_full ^= 1; - ui2_hsplit_t(&filters, 20.0f, &button, &filters); - if (ui2_do_button(&config.b_filter_pw, "No password", config.b_filter_pw, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&filters, 20.0f, &button, &filters); + if (ui_do_button(&config.b_filter_pw, "No password", config.b_filter_pw, &button, ui_draw_checkbox, 0)) config.b_filter_pw ^= 1; - ui2_hsplit_t(&filters, 2.0f, &button, &filters); // ping - ui2_hsplit_t(&filters, 20.0f, &button, &filters); + ui_hsplit_t(&filters, 2.0f, &button, &filters); // ping + ui_hsplit_t(&filters, 20.0f, &button, &filters); { RECT editbox; - ui2_vsplit_l(&button, 40.0f, &editbox, &button); - ui2_vsplit_l(&button, 5.0f, &button, &button); + ui_vsplit_l(&button, 40.0f, &editbox, &button); + ui_vsplit_l(&button, 5.0f, &button, &button); char buf[8]; sprintf(buf, "%d", config.b_filter_ping); - ui2_do_edit_box(&config.b_filter_ping, &editbox, buf, sizeof(buf)); + ui_do_edit_box(&config.b_filter_ping, &editbox, buf, sizeof(buf)); config.b_filter_ping = atoi(buf); - ui2_do_label(&button, "Maximum ping", 14.0f, -1); + ui_do_label(&button, "Maximum ping", 14.0f, -1); } - ui2_hsplit_t(&types, 20.0f, &button, &types); - if (ui2_do_button(&config.b_filter_gametype, "DM", config.b_filter_gametype&(1<<GAMETYPE_DM), &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&types, 20.0f, &button, &types); + if (ui_do_button(&config.b_filter_gametype, "DM", config.b_filter_gametype&(1<<GAMETYPE_DM), &button, ui_draw_checkbox, 0)) config.b_filter_gametype ^= (1<<GAMETYPE_DM); - ui2_hsplit_t(&types, 20.0f, &button, &types); - if (ui2_do_button((char *)&config.b_filter_gametype + 1, "TDM", config.b_filter_gametype&(1<<GAMETYPE_TDM), &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&types, 20.0f, &button, &types); + if (ui_do_button((char *)&config.b_filter_gametype + 1, "TDM", config.b_filter_gametype&(1<<GAMETYPE_TDM), &button, ui_draw_checkbox, 0)) config.b_filter_gametype ^= (1<<GAMETYPE_TDM); - ui2_hsplit_t(&types, 20.0f, &button, &types); - if (ui2_do_button((char *)&config.b_filter_gametype + 2, "CTF", config.b_filter_gametype&(1<<GAMETYPE_CTF), &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&types, 20.0f, &button, &types); + if (ui_do_button((char *)&config.b_filter_gametype + 2, "CTF", config.b_filter_gametype&(1<<GAMETYPE_CTF), &button, ui_draw_checkbox, 0)) config.b_filter_gametype ^= (1<<GAMETYPE_CTF); // render status - ui2_draw_rect(&status, vec4(1,1,1,0.25f), CORNER_B, 5.0f); - ui2_vmargin(&status, 50.0f, &status); + ui_draw_rect(&status, vec4(1,1,1,0.25f), CORNER_B, 5.0f); + ui_vmargin(&status, 50.0f, &status); char buf[128]; sprintf(buf, "%d of %d servers", client_serverbrowse_sorted_num(), client_serverbrowse_num()); - ui2_do_label(&status, buf, 14.0f, -1); + ui_do_label(&status, buf, 14.0f, -1); // render toolbox { RECT buttons, button; - ui2_hsplit_b(&toolbox, 25.0f, &toolbox, &buttons); + ui_hsplit_b(&toolbox, 25.0f, &toolbox, &buttons); - ui2_vsplit_r(&buttons, 100.0f, &buttons, &button); - ui2_vmargin(&button, 2.0f, &button); + ui_vsplit_r(&buttons, 100.0f, &buttons, &button); + ui_vmargin(&button, 2.0f, &button); static int join_button = 0; - if(ui2_do_button(&join_button, "Connect", 0, &button, ui2_draw_menu_button, 0)) + if(ui_do_button(&join_button, "Connect", 0, &button, ui_draw_menu_button, 0)) client_connect(config.ui_server_address); - ui2_vsplit_r(&buttons, 20.0f, &buttons, &button); - ui2_vsplit_r(&buttons, 100.0f, &buttons, &button); - ui2_vmargin(&button, 2.0f, &button); + ui_vsplit_r(&buttons, 20.0f, &buttons, &button); + ui_vsplit_r(&buttons, 100.0f, &buttons, &button); + ui_vmargin(&button, 2.0f, &button); static int refresh_button = 0; - if(ui2_do_button(&refresh_button, "Refresh", 0, &button, ui2_draw_menu_button, 0)) + if(ui_do_button(&refresh_button, "Refresh", 0, &button, ui_draw_menu_button, 0)) { if(config.ui_page == PAGE_INTERNET) client_serverbrowse_refresh(0); @@ -1398,10 +1111,10 @@ static void menu2_render_serverbrowser(RECT main_view) client_serverbrowse_refresh(1); } - ui2_hsplit_t(&toolbox, 20.0f, &button, &toolbox); - ui2_do_label(&button, "Host address:", 14.0f, -1); - ui2_vsplit_l(&button, 100.0f, 0, &button); - ui2_do_edit_box(&config.ui_server_address, &button, config.ui_server_address, sizeof(config.ui_server_address)); + ui_hsplit_t(&toolbox, 20.0f, &button, &toolbox); + ui_do_label(&button, "Host address:", 14.0f, -1); + ui_vsplit_l(&button, 100.0f, 0, &button); + ui_do_edit_box(&config.ui_server_address, &button, config.ui_server_address, sizeof(config.ui_server_address)); } } @@ -1409,43 +1122,43 @@ static void menu2_render_settings_player(RECT main_view) { RECT button; RECT skinselection; - ui2_vsplit_l(&main_view, 300.0f, &main_view, &skinselection); + ui_vsplit_l(&main_view, 300.0f, &main_view, &skinselection); - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); // render settings { - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - ui2_do_label(&button, "Name:", 14.0, -1); - ui2_vsplit_l(&button, 80.0f, 0, &button); - ui2_vsplit_l(&button, 180.0f, &button, 0); - ui2_do_edit_box(config.player_name, &button, config.player_name, sizeof(config.player_name)); - - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.cl_dynamic_camera, "Dynamic camera", config.cl_dynamic_camera, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + ui_do_label(&button, "Name:", 14.0, -1); + ui_vsplit_l(&button, 80.0f, 0, &button); + ui_vsplit_l(&button, 180.0f, &button, 0); + ui_do_edit_box(config.player_name, &button, config.player_name, sizeof(config.player_name)); + + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.cl_dynamic_camera, "Dynamic camera", config.cl_dynamic_camera, &button, ui_draw_checkbox, 0)) config.cl_dynamic_camera ^= 1; - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.cl_autoswitch_weapons, "Switch weapon on pickup", config.cl_autoswitch_weapons, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.cl_autoswitch_weapons, "Switch weapon on pickup", config.cl_autoswitch_weapons, &button, ui_draw_checkbox, 0)) config.cl_autoswitch_weapons ^= 1; - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.cl_nameplates, "Show name plates", config.cl_nameplates, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.cl_nameplates, "Show name plates", config.cl_nameplates, &button, ui_draw_checkbox, 0)) config.cl_nameplates ^= 1; if(config.cl_nameplates) { - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - ui2_vsplit_l(&button, 15.0f, 0, &button); - if (ui2_do_button(&config.cl_nameplates_always, "Always show name plates", config.cl_nameplates_always, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + ui_vsplit_l(&button, 15.0f, 0, &button); + if (ui_do_button(&config.cl_nameplates_always, "Always show name plates", config.cl_nameplates_always, &button, ui_draw_checkbox, 0)) config.cl_nameplates_always ^= 1; } - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.player_color_body, "Custom colors", config.player_use_custom_color, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.player_color_body, "Custom colors", config.player_use_custom_color, &button, ui_draw_checkbox, 0)) config.player_use_custom_color = config.player_use_custom_color?0:1; if(config.player_use_custom_color) @@ -1462,60 +1175,60 @@ static void menu2_render_settings_player(RECT main_view) for(int i = 0; i < 2; i++) { RECT text; - ui2_hsplit_t(&main_view, 20.0f, &text, &main_view); - ui2_vsplit_l(&text, 15.0f, 0, &text); - ui2_do_label(&text, parts[i], 14.0f, -1); + ui_hsplit_t(&main_view, 20.0f, &text, &main_view); + ui_vsplit_l(&text, 15.0f, 0, &text); + ui_do_label(&text, parts[i], 14.0f, -1); int prevcolor = *colors[i]; int color = 0; for(int s = 0; s < 3; s++) { RECT text; - ui2_hsplit_t(&main_view, 19.0f, &button, &main_view); - ui2_vsplit_l(&button, 30.0f, 0, &button); - ui2_vsplit_l(&button, 30.0f, &text, &button); - ui2_vsplit_r(&button, 5.0f, &button, 0); - ui2_hsplit_t(&button, 4.0f, 0, &button); + ui_hsplit_t(&main_view, 19.0f, &button, &main_view); + ui_vsplit_l(&button, 30.0f, 0, &button); + ui_vsplit_l(&button, 30.0f, &text, &button); + ui_vsplit_r(&button, 5.0f, &button, 0); + ui_hsplit_t(&button, 4.0f, 0, &button); float k = ((prevcolor>>((2-s)*8))&0xff) / 255.0f; - k = ui2_do_scrollbar_h(&color_slider[i][s], &button, k); + k = ui_do_scrollbar_h(&color_slider[i][s], &button, k); color <<= 8; color += clamp((int)(k*255), 0, 255); - ui2_do_label(&text, labels[s], 15.0f, -1); + ui_do_label(&text, labels[s], 15.0f, -1); } *colors[i] = color; - ui2_hsplit_t(&main_view, 5.0f, 0, &main_view); + ui_hsplit_t(&main_view, 5.0f, 0, &main_view); } } } // draw header RECT header, footer; - ui2_hsplit_t(&skinselection, 20, &header, &skinselection); - ui2_draw_rect(&header, vec4(1,1,1,0.25f), CORNER_T, 5.0f); - ui2_do_label(&header, "Skins", 18.0f, 0); + ui_hsplit_t(&skinselection, 20, &header, &skinselection); + ui_draw_rect(&header, vec4(1,1,1,0.25f), CORNER_T, 5.0f); + ui_do_label(&header, "Skins", 18.0f, 0); // draw footers - ui2_hsplit_b(&skinselection, 20, &skinselection, &footer); - ui2_draw_rect(&footer, vec4(1,1,1,0.25f), CORNER_B, 5.0f); - ui2_vsplit_l(&footer, 10.0f, 0, &footer); + ui_hsplit_b(&skinselection, 20, &skinselection, &footer); + ui_draw_rect(&footer, vec4(1,1,1,0.25f), CORNER_B, 5.0f); + ui_vsplit_l(&footer, 10.0f, 0, &footer); // modes - ui2_draw_rect(&skinselection, vec4(0,0,0,0.15f), 0, 0); + ui_draw_rect(&skinselection, vec4(0,0,0,0.15f), 0, 0); RECT scroll; - ui2_vsplit_r(&skinselection, 15, &skinselection, &scroll); + ui_vsplit_r(&skinselection, 15, &skinselection, &scroll); RECT list = skinselection; - ui2_hsplit_t(&list, 50, &button, &list); + ui_hsplit_t(&list, 50, &button, &list); int num = (int)(skinselection.h/button.h); static float scrollvalue = 0; static int scrollbar = 0; - ui2_hmargin(&scroll, 5.0f, &scroll); - scrollvalue = ui2_do_scrollbar_v(&scrollbar, &scroll, scrollvalue); + ui_hmargin(&scroll, 5.0f, &scroll); + scrollvalue = ui_do_scrollbar_v(&scrollbar, &scroll, scrollvalue); int start = (int)((skin_num()-num)*scrollvalue); if(start < 0) @@ -1546,22 +1259,22 @@ static void menu2_render_settings_player(RECT main_view) info.texture = s->color_texture; } - info.size = ui2_scale()*50.0f; + info.size = ui_scale()*50.0f; RECT icon; RECT text; - ui2_vsplit_l(&button, 50.0f, &icon, &text); + ui_vsplit_l(&button, 50.0f, &icon, &text); - if(ui2_do_button(s, "", selected, &button, ui2_draw_list_row, 0)) + if(ui_do_button(s, "", selected, &button, ui_draw_list_row, 0)) config_set_player_skin(&config, s->name); - ui2_hsplit_t(&text, 12.0f, 0, &text); // some margin from the top - ui2_do_label(&text, buf, 18.0f, 0); + ui_hsplit_t(&text, 12.0f, 0, &text); // some margin from the top + ui_do_label(&text, buf, 18.0f, 0); - ui2_hsplit_t(&icon, 5.0f, 0, &icon); // some margin from the top + ui_hsplit_t(&icon, 5.0f, 0, &icon); // some margin from the top render_tee(&state, &info, 0, vec2(1, 0), vec2(icon.x+icon.w/2, icon.y+icon.h/2)); - ui2_hsplit_t(&list, 50, &button, &list); + ui_hsplit_t(&list, 50, &button, &list); } } @@ -1569,17 +1282,17 @@ typedef void (*assign_func_callback)(CONFIGURATION *config, int value); static void menu2_render_settings_controls(RECT main_view) { - ui2_vsplit_l(&main_view, 300.0f, &main_view, 0); + ui_vsplit_l(&main_view, 300.0f, &main_view, 0); { RECT button, label; - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - ui2_vsplit_l(&button, 110.0f, &label, &button); - ui2_do_label(&label, "Mouse sens.", 14.0f, -1); - ui2_hmargin(&button, 2.0f, &button); - config.inp_mousesens = (int)(ui2_do_scrollbar_h(&config.inp_mousesens, &button, config.inp_mousesens/500.0f)*500.0f); - //*key.key = ui2_do_key_reader(key.key, &button, *key.key); - ui2_hsplit_t(&main_view, 20.0f, 0, &main_view); + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + ui_vsplit_l(&button, 110.0f, &label, &button); + ui_do_label(&label, "Mouse sens.", 14.0f, -1); + ui_hmargin(&button, 2.0f, &button); + config.inp_mousesens = (int)(ui_do_scrollbar_h(&config.inp_mousesens, &button, config.inp_mousesens/500.0f)*500.0f); + //*key.key = ui_do_key_reader(key.key, &button, *key.key); + ui_hsplit_t(&main_view, 20.0f, 0, &main_view); } typedef struct @@ -1615,12 +1328,12 @@ static void menu2_render_settings_controls(RECT main_view) { KEYINFO key = keys[i]; RECT button, label; - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - ui2_vsplit_l(&button, 110.0f, &label, &button); + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + ui_vsplit_l(&button, 110.0f, &label, &button); - ui2_do_label(&label, key.name, 14.0f, -1); - *key.key = ui2_do_key_reader(key.key, &button, *key.key); - ui2_hsplit_t(&main_view, 5.0f, 0, &main_view); + ui_do_label(&label, key.name, 14.0f, -1); + *key.key = ui_do_key_reader(key.key, &button, *key.key); + ui_hsplit_t(&main_view, 5.0f, 0, &main_view); } } @@ -1637,43 +1350,43 @@ static void menu2_render_settings_graphics(RECT main_view) num_modes = gfx_get_video_modes(modes, MAX_RESOLUTIONS); RECT modelist; - ui2_vsplit_l(&main_view, 300.0f, &main_view, &modelist); + ui_vsplit_l(&main_view, 300.0f, &main_view, &modelist); // draw allmodes switch RECT header, footer; - ui2_hsplit_t(&modelist, 20, &button, &modelist); - if (ui2_do_button(&config.gfx_display_all_modes, "Show only supported", config.gfx_display_all_modes^1, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&modelist, 20, &button, &modelist); + if (ui_do_button(&config.gfx_display_all_modes, "Show only supported", config.gfx_display_all_modes^1, &button, ui_draw_checkbox, 0)) { config.gfx_display_all_modes ^= 1; num_modes = gfx_get_video_modes(modes, MAX_RESOLUTIONS); } // draw header - ui2_hsplit_t(&modelist, 20, &header, &modelist); - ui2_draw_rect(&header, vec4(1,1,1,0.25f), CORNER_T, 5.0f); - ui2_do_label(&header, "Display Modes", 14.0f, 0); + ui_hsplit_t(&modelist, 20, &header, &modelist); + ui_draw_rect(&header, vec4(1,1,1,0.25f), CORNER_T, 5.0f); + ui_do_label(&header, "Display Modes", 14.0f, 0); // draw footers - ui2_hsplit_b(&modelist, 20, &modelist, &footer); + ui_hsplit_b(&modelist, 20, &modelist, &footer); sprintf(buf, "Current: %dx%d %d bit", config.gfx_screen_width, config.gfx_screen_height, config.gfx_color_depth); - ui2_draw_rect(&footer, vec4(1,1,1,0.25f), CORNER_B, 5.0f); - ui2_vsplit_l(&footer, 10.0f, 0, &footer); - ui2_do_label(&footer, buf, 14.0f, -1); + ui_draw_rect(&footer, vec4(1,1,1,0.25f), CORNER_B, 5.0f); + ui_vsplit_l(&footer, 10.0f, 0, &footer); + ui_do_label(&footer, buf, 14.0f, -1); // modes - ui2_draw_rect(&modelist, vec4(0,0,0,0.15f), 0, 0); + ui_draw_rect(&modelist, vec4(0,0,0,0.15f), 0, 0); RECT scroll; - ui2_vsplit_r(&modelist, 15, &modelist, &scroll); + ui_vsplit_r(&modelist, 15, &modelist, &scroll); RECT list = modelist; - ui2_hsplit_t(&list, 20, &button, &list); + ui_hsplit_t(&list, 20, &button, &list); int num = (int)(modelist.h/button.h); static float scrollvalue = 0; static int scrollbar = 0; - ui2_hmargin(&scroll, 5.0f, &scroll); - scrollvalue = ui2_do_scrollbar_v(&scrollbar, &scroll, scrollvalue); + ui_hmargin(&scroll, 5.0f, &scroll); + scrollvalue = ui_do_scrollbar_v(&scrollbar, &scroll, scrollvalue); int start = (int)((num_modes-num)*scrollvalue); if(start < 0) @@ -1696,7 +1409,7 @@ static void menu2_render_settings_graphics(RECT main_view) } sprintf(buf, " %dx%d %d bit", modes[i].width, modes[i].height, depth); - if(ui2_do_button(&modes[i], buf, selected, &button, ui2_draw_list_row, 0)) + if(ui_do_button(&modes[i], buf, selected, &button, ui_draw_list_row, 0)) { config.gfx_color_depth = depth; config.gfx_screen_width = modes[i].width; @@ -1705,24 +1418,24 @@ static void menu2_render_settings_graphics(RECT main_view) need_restart = true; } - ui2_hsplit_t(&list, 20, &button, &list); + ui_hsplit_t(&list, 20, &button, &list); } // switches - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.gfx_fullscreen, "Fullscreen", config.gfx_fullscreen, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.gfx_fullscreen, "Fullscreen", config.gfx_fullscreen, &button, ui_draw_checkbox, 0)) { config.gfx_fullscreen ^= 1; need_restart = true; } - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.gfx_vsync, "V-Sync", config.gfx_vsync, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.gfx_vsync, "V-Sync", config.gfx_vsync, &button, ui_draw_checkbox, 0)) config.gfx_vsync ^= 1; - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.gfx_fsaa_samples, "FSAA samples", config.gfx_fsaa_samples, &button, ui2_draw_checkbox_number, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.gfx_fsaa_samples, "FSAA samples", config.gfx_fsaa_samples, &button, ui_draw_checkbox_number, 0)) { if(config.gfx_fsaa_samples < 2) config.gfx_fsaa_samples = 2; else if(config.gfx_fsaa_samples < 4) config.gfx_fsaa_samples = 4; @@ -1733,58 +1446,58 @@ static void menu2_render_settings_graphics(RECT main_view) need_restart = true; } - ui2_hsplit_t(&main_view, 40.0f, &button, &main_view); - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.gfx_texture_quality, "Quality Textures", config.gfx_texture_quality, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 40.0f, &button, &main_view); + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.gfx_texture_quality, "Quality Textures", config.gfx_texture_quality, &button, ui_draw_checkbox, 0)) { config.gfx_texture_quality ^= 1; need_restart = true; } - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.gfx_texture_compression, "Texture Compression", config.gfx_texture_compression, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.gfx_texture_compression, "Texture Compression", config.gfx_texture_compression, &button, ui_draw_checkbox, 0)) { config.gfx_texture_compression ^= 1; need_restart = true; } - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.gfx_high_detail, "High Detail", config.gfx_high_detail, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.gfx_high_detail, "High Detail", config.gfx_high_detail, &button, ui_draw_checkbox, 0)) config.gfx_high_detail ^= 1; // RECT text; - ui2_hsplit_t(&main_view, 20.0f, 0, &main_view); - ui2_hsplit_t(&main_view, 20.0f, &text, &main_view); - //ui2_vsplit_l(&text, 15.0f, 0, &text); - ui2_do_label(&text, "UI Color", 14.0f, -1); + ui_hsplit_t(&main_view, 20.0f, 0, &main_view); + ui_hsplit_t(&main_view, 20.0f, &text, &main_view); + //ui_vsplit_l(&text, 15.0f, 0, &text); + ui_do_label(&text, "UI Color", 14.0f, -1); const char *labels[] = {"Hue", "Sat.", "Lht.", "Alpha"}; int *color_slider[4] = {&config.ui_color_hue, &config.ui_color_sat, &config.ui_color_lht, &config.ui_color_alpha}; for(int s = 0; s < 4; s++) { RECT text; - ui2_hsplit_t(&main_view, 19.0f, &button, &main_view); - ui2_vmargin(&button, 15.0f, &button); - ui2_vsplit_l(&button, 30.0f, &text, &button); - ui2_vsplit_r(&button, 5.0f, &button, 0); - ui2_hsplit_t(&button, 4.0f, 0, &button); + ui_hsplit_t(&main_view, 19.0f, &button, &main_view); + ui_vmargin(&button, 15.0f, &button); + ui_vsplit_l(&button, 30.0f, &text, &button); + ui_vsplit_r(&button, 5.0f, &button, 0); + ui_hsplit_t(&button, 4.0f, 0, &button); float k = (*color_slider[s]) / 255.0f; - k = ui2_do_scrollbar_h(color_slider[s], &button, k); + k = ui_do_scrollbar_h(color_slider[s], &button, k); *color_slider[s] = (int)(k*255.0f); - ui2_do_label(&text, labels[s], 15.0f, -1); + ui_do_label(&text, labels[s], 15.0f, -1); } } static void menu2_render_settings_sound(RECT main_view) { RECT button; - ui2_vsplit_l(&main_view, 300.0f, &main_view, 0); + ui_vsplit_l(&main_view, 300.0f, &main_view, 0); - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.snd_enable, "Use Sounds", config.snd_enable, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.snd_enable, "Use Sounds", config.snd_enable, &button, ui_draw_checkbox, 0)) { config.snd_enable ^= 1; need_restart = true; @@ -1793,19 +1506,19 @@ static void menu2_render_settings_sound(RECT main_view) if(!config.snd_enable) return; - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - if (ui2_do_button(&config.snd_nonactive_mute, "Mute when not active", config.snd_nonactive_mute, &button, ui2_draw_checkbox, 0)) + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + if (ui_do_button(&config.snd_nonactive_mute, "Mute when not active", config.snd_nonactive_mute, &button, ui_draw_checkbox, 0)) config.snd_nonactive_mute ^= 1; // sample rate box { char buf[64]; sprintf(buf, "%d", config.snd_rate); - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - ui2_do_label(&button, "Sample Rate", 14.0f, -1); - ui2_vsplit_l(&button, 110.0f, 0, &button); - ui2_vsplit_l(&button, 180.0f, &button, 0); - ui2_do_edit_box(&config.snd_rate, &button, buf, sizeof(buf)); + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + ui_do_label(&button, "Sample Rate", 14.0f, -1); + ui_vsplit_l(&button, 110.0f, 0, &button); + ui_vsplit_l(&button, 180.0f, &button, 0); + ui_do_edit_box(&config.snd_rate, &button, buf, sizeof(buf)); int before = config.snd_rate; config.snd_rate = atoi(buf); @@ -1819,13 +1532,13 @@ static void menu2_render_settings_sound(RECT main_view) // volume slider { RECT button, label; - ui2_hsplit_t(&main_view, 5.0f, &button, &main_view); - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - ui2_vsplit_l(&button, 110.0f, &label, &button); - ui2_hmargin(&button, 2.0f, &button); - ui2_do_label(&label, "Sound Volume", 14.0f, -1); - config.snd_volume = (int)(ui2_do_scrollbar_h(&config.snd_volume, &button, config.snd_volume/100.0f)*100.0f); - ui2_hsplit_t(&main_view, 20.0f, 0, &main_view); + ui_hsplit_t(&main_view, 5.0f, &button, &main_view); + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + ui_vsplit_l(&button, 110.0f, &label, &button); + ui_hmargin(&button, 2.0f, &button); + ui_do_label(&label, "Sound Volume", 14.0f, -1); + config.snd_volume = (int)(ui_do_scrollbar_h(&config.snd_volume, &button, config.snd_volume/100.0f)*100.0f); + ui_hsplit_t(&main_view, 20.0f, 0, &main_view); } } @@ -1833,14 +1546,14 @@ static void menu2_render_settings_sound(RECT main_view) static void menu2_render_settings_network(RECT main_view) { RECT button; - ui2_vsplit_l(&main_view, 300.0f, &main_view, 0); + ui_vsplit_l(&main_view, 300.0f, &main_view, 0); { - ui2_hsplit_t(&main_view, 20.0f, &button, &main_view); - ui2_do_label(&button, "Rcon Password", 14.0, -1); - ui2_vsplit_l(&button, 110.0f, 0, &button); - ui2_vsplit_l(&button, 180.0f, &button, 0); - ui2_do_edit_box(&config.rcon_password, &button, config.rcon_password, sizeof(config.rcon_password), true); + ui_hsplit_t(&main_view, 20.0f, &button, &main_view); + ui_do_label(&button, "Rcon Password", 14.0, -1); + ui_vsplit_l(&button, 110.0f, 0, &button); + ui_vsplit_l(&button, 180.0f, &button, 0); + ui_do_edit_box(&config.rcon_password, &button, config.rcon_password, sizeof(config.rcon_password), true); } } @@ -1850,12 +1563,12 @@ static void menu2_render_settings(RECT main_view) // render background RECT temp, tabbar; - ui2_vsplit_r(&main_view, 120.0f, &main_view, &tabbar); - ui2_draw_rect(&main_view, color_tabbar_active, CORNER_B|CORNER_TL, 10.0f); - ui2_hsplit_t(&tabbar, 50.0f, &temp, &tabbar); - ui2_draw_rect(&temp, color_tabbar_active, CORNER_R, 10.0f); + ui_vsplit_r(&main_view, 120.0f, &main_view, &tabbar); + ui_draw_rect(&main_view, color_tabbar_active, CORNER_B|CORNER_TL, 10.0f); + ui_hsplit_t(&tabbar, 50.0f, &temp, &tabbar); + ui_draw_rect(&temp, color_tabbar_active, CORNER_R, 10.0f); - ui2_hsplit_t(&main_view, 10.0f, 0, &main_view); + ui_hsplit_t(&main_view, 10.0f, 0, &main_view); RECT button; @@ -1864,13 +1577,13 @@ static void menu2_render_settings(RECT main_view) for(int i = 0; i < num_tabs; i++) { - ui2_hsplit_t(&tabbar, 10, &button, &tabbar); - ui2_hsplit_t(&tabbar, 26, &button, &tabbar); - if(ui2_do_button(tabs[i], tabs[i], settings_page == i, &button, ui2_draw_settings_tab_button, 0)) + ui_hsplit_t(&tabbar, 10, &button, &tabbar); + ui_hsplit_t(&tabbar, 26, &button, &tabbar); + if(ui_do_button(tabs[i], tabs[i], settings_page == i, &button, ui_draw_settings_tab_button, 0)) settings_page = i; } - ui2_margin(&main_view, 10.0f, &main_view); + ui_margin(&main_view, 10.0f, &main_view); if(settings_page == 0) menu2_render_settings_player(main_view); @@ -1886,40 +1599,40 @@ static void menu2_render_settings(RECT main_view) if(need_restart) { RECT restart_warning; - ui2_hsplit_b(&main_view, 40, &main_view, &restart_warning); - ui2_do_label(&restart_warning, "You must restart Teewars for all settings to take effect.", 15.0f, -1, 220); + ui_hsplit_b(&main_view, 40, &main_view, &restart_warning); + ui_do_label(&restart_warning, "You must restart Teewars for all settings to take effect.", 15.0f, -1, 220); } } static void menu2_render_news(RECT main_view) { - ui2_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f); + ui_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f); } static void menu2_render_game(RECT main_view) { RECT button; - ui2_hsplit_t(&main_view, 45.0f, &main_view, 0); - ui2_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f); + ui_hsplit_t(&main_view, 45.0f, &main_view, 0); + ui_draw_rect(&main_view, color_tabbar_active, CORNER_ALL, 10.0f); - ui2_hsplit_t(&main_view, 10.0f, 0, &main_view); - ui2_hsplit_t(&main_view, 25.0f, &main_view, 0); - ui2_vmargin(&main_view, 10.0f, &main_view); + ui_hsplit_t(&main_view, 10.0f, 0, &main_view); + ui_hsplit_t(&main_view, 25.0f, &main_view, 0); + ui_vmargin(&main_view, 10.0f, &main_view); - ui2_vsplit_r(&main_view, 120.0f, &main_view, &button); + ui_vsplit_r(&main_view, 120.0f, &main_view, &button); static int disconnect_button = 0; - if(ui2_do_button(&disconnect_button, "Disconnect", 0, &button, ui2_draw_menu_button, 0)) + if(ui_do_button(&disconnect_button, "Disconnect", 0, &button, ui_draw_menu_button, 0)) client_disconnect(); if(local_info && gameobj) { if(local_info->team != -1) { - ui2_vsplit_l(&main_view, 10.0f, &button, &main_view); - ui2_vsplit_l(&main_view, 120.0f, &button, &main_view); + ui_vsplit_l(&main_view, 10.0f, &button, &main_view); + ui_vsplit_l(&main_view, 120.0f, &button, &main_view); static int spectate_button = 0; - if(ui2_do_button(&spectate_button, "Spectate", 0, &button, ui2_draw_menu_button, 0)) + if(ui_do_button(&spectate_button, "Spectate", 0, &button, ui_draw_menu_button, 0)) { config.cl_team = -1; menu_active = false; @@ -1930,10 +1643,10 @@ static void menu2_render_game(RECT main_view) { if(local_info->team != 0) { - ui2_vsplit_l(&main_view, 10.0f, &button, &main_view); - ui2_vsplit_l(&main_view, 120.0f, &button, &main_view); + ui_vsplit_l(&main_view, 10.0f, &button, &main_view); + ui_vsplit_l(&main_view, 120.0f, &button, &main_view); static int spectate_button = 0; - if(ui2_do_button(&spectate_button, "Join Game", 0, &button, ui2_draw_menu_button, 0)) + if(ui_do_button(&spectate_button, "Join Game", 0, &button, ui_draw_menu_button, 0)) { config.cl_team = 0; menu_active = false; @@ -1944,10 +1657,10 @@ static void menu2_render_game(RECT main_view) { if(local_info->team != 0) { - ui2_vsplit_l(&main_view, 10.0f, &button, &main_view); - ui2_vsplit_l(&main_view, 120.0f, &button, &main_view); + ui_vsplit_l(&main_view, 10.0f, &button, &main_view); + ui_vsplit_l(&main_view, 120.0f, &button, &main_view); static int spectate_button = 0; - if(ui2_do_button(&spectate_button, "Join Red", 0, &button, ui2_draw_menu_button, 0)) + if(ui_do_button(&spectate_button, "Join Red", 0, &button, ui_draw_menu_button, 0)) { config.cl_team = 0; menu_active = false; @@ -1956,10 +1669,10 @@ static void menu2_render_game(RECT main_view) if(local_info->team != 1) { - ui2_vsplit_l(&main_view, 10.0f, &button, &main_view); - ui2_vsplit_l(&main_view, 120.0f, &button, &main_view); + ui_vsplit_l(&main_view, 10.0f, &button, &main_view); + ui_vsplit_l(&main_view, 120.0f, &button, &main_view); static int spectate_button = 0; - if(ui2_do_button(&spectate_button, "Join Blue", 0, &button, ui2_draw_menu_button, 0)) + if(ui_do_button(&spectate_button, "Join Blue", 0, &button, ui_draw_menu_button, 0)) { config.cl_team = 1; menu_active = false; @@ -2028,7 +1741,7 @@ int menu2_render() info.texture = skin_get(i)->color_texture; info.color_feet = info.color_body = skin_get_color(colors[c]); //info.color_feet = info.color_body = vec4(1,1,1,1); - info.size = 1.0f; //ui2_scale()*16.0f; + info.size = 1.0f; //ui_scale()*16.0f; //render_tee(&state, &info, 0, vec2(sinf(client_localtime()*3), cosf(client_localtime()*3)), vec2(1+x+c,1+y)); render_tee(&state, &info, 0, vec2(1,0), vec2(1+x+c,1+y)); } @@ -2037,21 +1750,20 @@ int menu2_render() return 0; } - RECT screen = *ui2_screen(); + RECT screen = *ui_screen(); gfx_mapscreen(screen.x, screen.y, screen.w, screen.h); if (0) { gfx_clear(0.65f,0.78f,0.9f); - //gfx_pretty_text_color(0.0f, 0.0f, 0.0f, 1.0f); - //gfx_pretty_text_color(0.0f, 0.0f, 0.0f, 1.0f); + for (int i = 0; i < 24; i++) { float size = i * 0.5 + 8; char temp[64]; sprintf(temp, "%f: Ingen tomte i jul", size); - gfx_pretty_text(50, 10 + i*int(size), size, temp, -1); + gfx_text(0, 50, 10 + i*int(size), size, temp, -1); gfx_text(gfx_font_set, 400, 10 + i*int(size), size, temp, -1); } @@ -2085,13 +1797,13 @@ int menu2_render() RECT main_view; // some margin around the screen - ui2_margin(&screen, 10.0f, &screen); + ui_margin(&screen, 10.0f, &screen); if(popup == POPUP_NONE) { // do tab bar - ui2_hsplit_t(&screen, 26.0f, &tab_bar, &main_view); - ui2_vmargin(&tab_bar, 20.0f, &tab_bar); + ui_hsplit_t(&screen, 26.0f, &tab_bar, &main_view); + ui_vmargin(&tab_bar, 20.0f, &tab_bar); menu2_render_menubar(tab_bar); // render current page @@ -2152,103 +1864,103 @@ int menu2_render() RECT box, part; box = screen; - ui2_vmargin(&box, 150.0f, &box); - ui2_hmargin(&box, 150.0f, &box); + ui_vmargin(&box, 150.0f, &box); + ui_hmargin(&box, 150.0f, &box); // render the box - ui2_draw_rect(&box, vec4(0,0,0,0.5f), CORNER_ALL, 15.0f); + ui_draw_rect(&box, vec4(0,0,0,0.5f), CORNER_ALL, 15.0f); - ui2_hsplit_t(&box, 20.f, &part, &box); - ui2_hsplit_t(&box, 24.f, &part, &box); - ui2_do_label(&part, title, 24.f, 0); - ui2_hsplit_t(&box, 20.f, &part, &box); - ui2_hsplit_t(&box, 24.f, &part, &box); - ui2_vmargin(&part, 20.f, &part); - ui2_do_label(&part, extra_text, 20.f, -1, (int)part.w); + ui_hsplit_t(&box, 20.f, &part, &box); + ui_hsplit_t(&box, 24.f, &part, &box); + ui_do_label(&part, title, 24.f, 0); + ui_hsplit_t(&box, 20.f, &part, &box); + ui_hsplit_t(&box, 24.f, &part, &box); + ui_vmargin(&part, 20.f, &part); + ui_do_label(&part, extra_text, 20.f, -1, (int)part.w); if(popup == POPUP_QUIT) { RECT yes, no; - ui2_hsplit_b(&box, 20.f, &box, &part); - ui2_hsplit_b(&box, 24.f, &box, &part); - ui2_vmargin(&part, 80.0f, &part); + ui_hsplit_b(&box, 20.f, &box, &part); + ui_hsplit_b(&box, 24.f, &box, &part); + ui_vmargin(&part, 80.0f, &part); - ui2_vsplit_mid(&part, &no, &yes); + ui_vsplit_mid(&part, &no, &yes); - ui2_vmargin(&yes, 20.0f, &yes); - ui2_vmargin(&no, 20.0f, &no); + ui_vmargin(&yes, 20.0f, &yes); + ui_vmargin(&no, 20.0f, &no); static int button_abort = 0; - if(ui2_do_button(&button_abort, "No", 0, &no, ui2_draw_menu_button, 0) || inp_key_down(KEY_ESC)) + if(ui_do_button(&button_abort, "No", 0, &no, ui_draw_menu_button, 0) || inp_key_down(KEY_ESC)) popup = POPUP_NONE; static int button_tryagain = 0; - if(ui2_do_button(&button_tryagain, "Yes", 0, &yes, ui2_draw_menu_button, 0) || inp_key_down(KEY_ENTER)) + if(ui_do_button(&button_tryagain, "Yes", 0, &yes, ui_draw_menu_button, 0) || inp_key_down(KEY_ENTER)) client_quit(); } else if(popup == POPUP_PASSWORD) { RECT label, textbox, tryagain, abort; - ui2_hsplit_b(&box, 20.f, &box, &part); - ui2_hsplit_b(&box, 24.f, &box, &part); - ui2_vmargin(&part, 80.0f, &part); + ui_hsplit_b(&box, 20.f, &box, &part); + ui_hsplit_b(&box, 24.f, &box, &part); + ui_vmargin(&part, 80.0f, &part); - ui2_vsplit_mid(&part, &abort, &tryagain); + ui_vsplit_mid(&part, &abort, &tryagain); - ui2_vmargin(&tryagain, 20.0f, &tryagain); - ui2_vmargin(&abort, 20.0f, &abort); + ui_vmargin(&tryagain, 20.0f, &tryagain); + ui_vmargin(&abort, 20.0f, &abort); static int button_abort = 0; - if(ui2_do_button(&button_abort, "Abort", 0, &abort, ui2_draw_menu_button, 0) || inp_key_down(KEY_ESC)) + if(ui_do_button(&button_abort, "Abort", 0, &abort, ui_draw_menu_button, 0) || inp_key_down(KEY_ESC)) popup = POPUP_NONE; static int button_tryagain = 0; - if(ui2_do_button(&button_tryagain, "Try again", 0, &tryagain, ui2_draw_menu_button, 0) || inp_key_down(KEY_ENTER)) + if(ui_do_button(&button_tryagain, "Try again", 0, &tryagain, ui_draw_menu_button, 0) || inp_key_down(KEY_ENTER)) { client_connect(config.ui_server_address); } - ui2_hsplit_b(&box, 60.f, &box, &part); - ui2_hsplit_b(&box, 24.f, &box, &part); + ui_hsplit_b(&box, 60.f, &box, &part); + ui_hsplit_b(&box, 24.f, &box, &part); - ui2_vsplit_l(&part, 60.0f, 0, &label); - ui2_vsplit_l(&label, 100.0f, 0, &textbox); - ui2_vsplit_l(&textbox, 20.0f, 0, &textbox); - ui2_vsplit_r(&textbox, 60.0f, &textbox, 0); - ui2_do_label(&label, "Password:", 20, -1); - ui2_do_edit_box(&config.password, &textbox, config.password, sizeof(config.password), true); + ui_vsplit_l(&part, 60.0f, 0, &label); + ui_vsplit_l(&label, 100.0f, 0, &textbox); + ui_vsplit_l(&textbox, 20.0f, 0, &textbox); + ui_vsplit_r(&textbox, 60.0f, &textbox, 0); + ui_do_label(&label, "Password:", 20, -1); + ui_do_edit_box(&config.password, &textbox, config.password, sizeof(config.password), true); } else if(popup == POPUP_FIRST_LAUNCH) { RECT label, textbox; - ui2_hsplit_b(&box, 20.f, &box, &part); - ui2_hsplit_b(&box, 24.f, &box, &part); - ui2_vmargin(&part, 80.0f, &part); + ui_hsplit_b(&box, 20.f, &box, &part); + ui_hsplit_b(&box, 24.f, &box, &part); + ui_vmargin(&part, 80.0f, &part); static int enter_button = 0; - if(ui2_do_button(&enter_button, "Enter", 0, &part, ui2_draw_menu_button, 0) || inp_key_down(KEY_ENTER)) + if(ui_do_button(&enter_button, "Enter", 0, &part, ui_draw_menu_button, 0) || inp_key_down(KEY_ENTER)) popup = POPUP_NONE; - ui2_hsplit_b(&box, 60.f, &box, &part); - ui2_hsplit_b(&box, 24.f, &box, &part); + ui_hsplit_b(&box, 60.f, &box, &part); + ui_hsplit_b(&box, 24.f, &box, &part); - ui2_vsplit_l(&part, 60.0f, 0, &label); - ui2_vsplit_l(&label, 100.0f, 0, &textbox); - ui2_vsplit_l(&textbox, 20.0f, 0, &textbox); - ui2_vsplit_r(&textbox, 60.0f, &textbox, 0); - ui2_do_label(&label, "Nickname:", 20, -1); - ui2_do_edit_box(&config.player_name, &textbox, config.player_name, sizeof(config.player_name)); + ui_vsplit_l(&part, 60.0f, 0, &label); + ui_vsplit_l(&label, 100.0f, 0, &textbox); + ui_vsplit_l(&textbox, 20.0f, 0, &textbox); + ui_vsplit_r(&textbox, 60.0f, &textbox, 0); + ui_do_label(&label, "Nickname:", 20, -1); + ui_do_edit_box(&config.player_name, &textbox, config.player_name, sizeof(config.player_name)); } else { - ui2_hsplit_b(&box, 20.f, &box, &part); - ui2_hsplit_b(&box, 24.f, &box, &part); - ui2_vmargin(&part, 120.0f, &part); + ui_hsplit_b(&box, 20.f, &box, &part); + ui_hsplit_b(&box, 24.f, &box, &part); + ui_vmargin(&part, 120.0f, &part); static int button = 0; - if(ui2_do_button(&button, button_text, 0, &part, ui2_draw_menu_button, 0) || inp_key_down(KEY_ESC) || inp_key_down(KEY_ENTER)) + if(ui_do_button(&button, button_text, 0, &part, ui_draw_menu_button, 0) || inp_key_down(KEY_ESC) || inp_key_down(KEY_ENTER)) { if(popup == POPUP_CONNECTING) client_disconnect(); @@ -2301,7 +2013,7 @@ void modmenu_render() if(mouse_y > gfx_screenheight()) mouse_y = gfx_screenheight(); // update the ui - RECT *screen = ui2_screen(); + RECT *screen = ui_screen(); mx = (mouse_x/(float)gfx_screenwidth())*screen->w; my = (mouse_y/(float)gfx_screenheight())*screen->h; diff --git a/src/game/client/gc_ui.cpp b/src/game/client/gc_ui.cpp new file mode 100644 index 00000000..8d47c971 --- /dev/null +++ b/src/game/client/gc_ui.cpp @@ -0,0 +1,282 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#include <engine/e_system.h> +#include <engine/e_interface.h> +#include <engine/e_config.h> +#include "gc_ui.h" + +/******************************************************** + UI +*********************************************************/ +static const void *hot_item = 0; +static const void *active_item = 0; +static const void *last_active_item = 0; +static const void *becomming_hot_item = 0; +static float mouse_x, mouse_y; /* in gui space */ +static float mouse_wx, mouse_wy; /* in world space */ +static unsigned mouse_buttons = 0; +static unsigned last_mouse_buttons = 0; + +float ui_mouse_x() { return mouse_x; } +float ui_mouse_y() { return mouse_y; } +float ui_mouse_world_x() { return mouse_wx; } +float ui_mouse_world_y() { return mouse_wy; } +int ui_mouse_button(int index) { return (mouse_buttons>>index)&1; } +int ui_mouse_button_clicked(int index) { return ui_mouse_button(index) && !((last_mouse_buttons>>index)&1) ; } + +void ui_set_hot_item(const void *id) { becomming_hot_item = id; } +void ui_set_active_item(const void *id) { active_item = id; if (id) last_active_item = id; } +void ui_clear_last_active_item() { last_active_item = 0; } +const void *ui_hot_item() { return hot_item; } +const void *ui_active_item() { return active_item; } +const void *ui_last_active_item() { return last_active_item; } + +int ui_update(float mx, float my, float mwx, float mwy, int buttons) +{ + mouse_x = mx; + mouse_y = my; + mouse_wx = mwx; + mouse_wy = mwy; + last_mouse_buttons = mouse_buttons; + mouse_buttons = buttons; + hot_item = becomming_hot_item; + if(active_item) + hot_item = active_item; + becomming_hot_item = 0; + return 0; +} + +int ui_mouse_inside(const RECT *r) +{ + if(mouse_x >= r->x && mouse_x <= r->x+r->w && mouse_y >= r->y && mouse_y <= r->y+r->h) + return 1; + return 0; +} + +static RECT screen = { 0.0f, 0.0f, 848.0f, 480.0f }; + +RECT *ui_screen() +{ + float aspect = gfx_screenaspect(); + float w, h; + + h = 600; + w = aspect*h; + + screen.w = w; + screen.h = h; + + return &screen; +} + +void ui_set_scale(float s) +{ + config.ui_scale = (int)(s*100.0f); +} + +float ui_scale() +{ + return config.ui_scale/100.0f; +} + +void ui_clip_enable(const RECT *r) +{ + float xscale = gfx_screenwidth()/ui_screen()->w; + float yscale = gfx_screenheight()/ui_screen()->h; + gfx_clip_enable((int)(r->x*xscale), (int)(r->y*yscale), (int)(r->w*xscale), (int)(r->h*yscale)); +} + +void ui_clip_disable() +{ + gfx_clip_disable(); +} + +void ui_hsplit_t(const RECT *original, float cut, RECT *top, RECT *bottom) +{ + RECT r = *original; + cut *= ui_scale(); + + if (top) + { + top->x = r.x; + top->y = r.y; + top->w = r.w; + top->h = cut; + } + + if (bottom) + { + bottom->x = r.x; + bottom->y = r.y + cut; + bottom->w = r.w; + bottom->h = r.h - cut; + } +} + +void ui_hsplit_b(const RECT *original, float cut, RECT *top, RECT *bottom) +{ + RECT r = *original; + cut *= ui_scale(); + + if (top) + { + top->x = r.x; + top->y = r.y; + top->w = r.w; + top->h = r.h - cut; + } + + if (bottom) + { + bottom->x = r.x; + bottom->y = r.y + r.h - cut; + bottom->w = r.w; + bottom->h = cut; + } +} + + +void ui_vsplit_mid(const RECT *original, RECT *left, RECT *right) +{ + RECT r = *original; + float cut = r.w/2; + + if (left) + { + left->x = r.x; + left->y = r.y; + left->w = cut; + left->h = r.h; + } + + if (right) + { + right->x = r.x + cut; + right->y = r.y; + right->w = r.w - cut; + right->h = r.h; + } +} + +void ui_vsplit_l(const RECT *original, float cut, RECT *left, RECT *right) +{ + RECT r = *original; + cut *= ui_scale(); + + if (left) + { + left->x = r.x; + left->y = r.y; + left->w = cut; + left->h = r.h; + } + + if (right) + { + right->x = r.x + cut; + right->y = r.y; + right->w = r.w - cut; + right->h = r.h; + } +} + +void ui_vsplit_r(const RECT *original, float cut, RECT *left, RECT *right) +{ + RECT r = *original; + cut *= ui_scale(); + + if (left) + { + left->x = r.x; + left->y = r.y; + left->w = r.w - cut; + left->h = r.h; + } + + if (right) + { + right->x = r.x + r.w - cut; + right->y = r.y; + right->w = cut; + right->h = r.h; + } +} + +void ui_margin(const RECT *original, float cut, RECT *other_rect) +{ + RECT r = *original; + cut *= ui_scale(); + + other_rect->x = r.x + cut; + other_rect->y = r.y + cut; + other_rect->w = r.w - 2*cut; + other_rect->h = r.h - 2*cut; +} + +void ui_vmargin(const RECT *original, float cut, RECT *other_rect) +{ + RECT r = *original; + cut *= ui_scale(); + + other_rect->x = r.x + cut; + other_rect->y = r.y; + other_rect->w = r.w - 2*cut; + other_rect->h = r.h; +} + +void ui_hmargin(const RECT *original, float cut, RECT *other_rect) +{ + RECT r = *original; + cut *= ui_scale(); + + other_rect->x = r.x; + other_rect->y = r.y + cut; + other_rect->w = r.w; + other_rect->h = r.h - 2*cut; +} + +int ui_do_button(const void *id, const char *text, int checked, const RECT *r, ui_draw_button_func draw_func, const void *extra) +{ + /* logic */ + int ret = 0; + int inside = ui_mouse_inside(r); + + if(ui_active_item() == id) + { + if(!ui_mouse_button(0)) + { + if(inside && checked >= 0) + ret = 1; + ui_set_active_item(0); + } + } + else if(ui_hot_item() == id) + { + if(ui_mouse_button(0)) + ui_set_active_item(id); + } + + if(inside) + ui_set_hot_item(id); + + if(draw_func) + draw_func(id, text, checked, r, extra); + return ret; +} + +void ui_do_label(const RECT *r, const char *text, float size, int align, int max_width) +{ + gfx_blend_normal(); + size *= ui_scale(); + if(align == 0) + { + float tw = gfx_text_width(0, size, text, max_width); + gfx_text(0, r->x + r->w/2-tw/2, r->y, size, text, max_width); + } + else if(align < 0) + gfx_text(0, r->x, r->y, size, text, max_width); + else if(align > 0) + { + float tw = gfx_text_width(0, size, text, max_width); + gfx_text(0, r->x + r->w-tw, r->y, size, text, max_width); + } +} diff --git a/src/game/client/gc_ui.h b/src/game/client/gc_ui.h new file mode 100644 index 00000000..92b8e19a --- /dev/null +++ b/src/game/client/gc_ui.h @@ -0,0 +1,64 @@ +/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */ +#ifndef _UI_H +#define _UI_H + +typedef struct +{ + float x, y, w, h; +} RECT; + +enum +{ + CORNER_TL=1, + CORNER_TR=2, + CORNER_BL=4, + CORNER_BR=8, + + CORNER_T=CORNER_TL|CORNER_TR, + CORNER_B=CORNER_BL|CORNER_BR, + CORNER_R=CORNER_TR|CORNER_BR, + CORNER_L=CORNER_TL|CORNER_BL, + + CORNER_ALL=CORNER_T|CORNER_B +}; + +int ui_update(float mx, float my, float mwx, float mwy, int buttons); + +float ui_mouse_x(); +float ui_mouse_y(); +float ui_mouse_world_x(); +float ui_mouse_world_y(); +int ui_mouse_button(int index); +int ui_mouse_button_clicked(int index); + +void ui_set_hot_item(const void *id); +void ui_set_active_item(const void *id); +void ui_clear_last_active_item(); +const void *ui_hot_item(); +const void *ui_active_item(); +const void *ui_last_active_item(); + +int ui_mouse_inside(const RECT *r); + +RECT *ui_screen(); +void ui_set_scale(float s); +float ui_scale(); +void ui_clip_enable(const RECT *r); +void ui_clip_disable(); + +void ui_hsplit_t(const RECT *original, float cut, RECT *top, RECT *bottom); +void ui_hsplit_b(const RECT *original, float cut, RECT *top, RECT *bottom); +void ui_vsplit_mid(const RECT *original, RECT *left, RECT *right); +void ui_vsplit_l(const RECT *original, float cut, RECT *left, RECT *right); +void ui_vsplit_r(const RECT *original, float cut, RECT *left, RECT *right); + +void ui_margin(const RECT *original, float cut, RECT *other_rect); +void ui_vmargin(const RECT *original, float cut, RECT *other_rect); +void ui_hmargin(const RECT *original, float cut, RECT *other_rect); + +typedef void (*ui_draw_button_func)(const void *id, const char *text, int checked, const RECT *r, const void *extra); +int ui_do_button(const void *id, const char *text, int checked, const RECT *r, ui_draw_button_func draw_func, const void *extra); +void ui_do_label(const RECT *r, const char *text, float size, int align, int max_width = -1); + + +#endif diff --git a/src/game/editor/array.h b/src/game/editor/array.h new file mode 100755 index 00000000..fe9f2739 --- /dev/null +++ b/src/game/editor/array.h @@ -0,0 +1,238 @@ + +template <class T> +class array +{ + // + // + void init() + { + list = 0; + clear(); + } + +public: + array() + { + init(); + } + + // + array(const array &other) + { + init(); + setsize(other.len()); + for(int i = 0; i < len(); i++) + (*this)[i] = other[i]; + } + + + // + // + virtual ~array() + { + delete [] list; + list = 0; + } + + // + // + void deleteall() + { + for(int i = 0; i < len(); i++) + delete list[i]; + + clear(); + } + + + // + // + void clear() + { + delete [] list; + + list_size = 1; + list = new T[1]; + num_elements = 0; + } + + int find(T val) + { + for(int i = 0; i < len(); i++) + if((*this)[i] == val) + return i; + return -1; + } + + bool exist(T val) + { + return find(val) != -1; + } + + // + // returns the number of elements in the list + // + int len() const + { + return num_elements; + } + + // + // This doesn't conserve the order in the list. Be careful + // + void removebyindexfast(int index) + { + //ASSUME(_Pos >= 0 && _Pos < num_elements); + list[index] = list[num_elements-1]; + setsize(len()-1); + } + + void removefast(const T& _Elem) + { + for(int i = 0; i < len(); i++) + if(list[i] == _Elem) + { + removebyindexfast(i); + return; + } + } + + // + // + void removebyindex(int index) + { + //ASSUME(_Pos >= 0 && _Pos < num_elements); + + for(int i = index+1; i < num_elements; i++) + list[i-1] = list[i]; + + setsize(len()-1); + } + + void insert(int index, const T& element) + { + int some_len = len(); + if (index < some_len) + setsize(some_len+1); + else + setsize(index + 1); + + for(int i = num_elements-2; i >= index; i--) + list[i+1] = list[i]; + + list[index] = element; + } + + bool remove(const T& element) + { + for(int i = 0; i < len(); i++) + if(list[i] == element) + { + removebyindex(i); + return true; + } + return false; + } + + // + // + int add(const T& element) + { + //if(num_elements == list_size) + setsize(len()+1); + list[num_elements-1] = element; + return num_elements-1; + } + + // + // + int add(const T& elem, int index) + { + setsize(len()+1); + + for(int i = num_elements-1; i > index; i--) + list[i] = list[i-1]; + + list[index] = elem; + + //num_elements++; + return num_elements-1; + } + + // + // + T& operator[] (int index) + { + return list[index]; + } + + const T& operator[] (int index) const + { + return list[index]; + } + + // + // + T *getptr() + { + return list; + } + + const T *getptr() const + { + return list; + } + + // + // + // + void setsize(int new_len) + { + if (list_size < new_len) + allocsize(new_len); + num_elements = new_len; + } + + // removes unnessasary data, returns how many bytes was earned + int optimize() + { + int Before = memoryusage(); + setsize(num_elements); + return Before - memoryusage(); + } + + // returns how much memory this dynamic array is using + int memoryusage() + { + return sizeof(array) + sizeof(T)*list_size; + } + + // + array &operator = (const array &other) + { + setsize(other.len()); + for(int i = 0; i < len(); i++) + (*this)[i] = other[i]; + return *this; + } +private: + void allocsize(int new_len) + { + list_size = new_len; + T *new_list = new T[list_size]; + + long end = num_elements < list_size ? num_elements : list_size; + for(int i = 0; i < end; i++) + new_list[i] = list[i]; + + delete [] list; + list = 0; + num_elements = num_elements < list_size ? num_elements : list_size; + list = new_list; + } + + T *list; + long list_size; + long num_elements; +}; + diff --git a/src/game/editor/ed_layer_game.cpp b/src/game/editor/ed_layer_game.cpp new file mode 100644 index 00000000..0e002559 --- /dev/null +++ b/src/game/editor/ed_layer_game.cpp @@ -0,0 +1,20 @@ +#include <game/client/gc_mapres_tilemap.h> +#include "editor.hpp" + + +LAYER_GAME::LAYER_GAME(int w, int h) +: LAYER_TILES(w, h) +{ + type_name = "Game"; + game = 1; +} + +LAYER_GAME::~LAYER_GAME() +{ +} + +void LAYER_GAME::render_properties(RECT *toolbox) +{ + LAYER_TILES::render_properties(toolbox); + image = -1; +} diff --git a/src/game/editor/ed_layer_quads.cpp b/src/game/editor/ed_layer_quads.cpp new file mode 100644 index 00000000..d58a9e0f --- /dev/null +++ b/src/game/editor/ed_layer_quads.cpp @@ -0,0 +1,361 @@ +#include "editor.hpp" +#include <game/g_math.h> + +LAYER_QUADS::LAYER_QUADS() +{ + type = LAYERTYPE_QUADS; + type_name = "Quads"; + image = -1; +} + +LAYER_QUADS::~LAYER_QUADS() +{ +} + +static void rotate(POINT *center, POINT *point, float rotation) +{ + int x = point->x - center->x; + int y = point->y - center->y; + point->x = (int)(x * cosf(rotation) - y * sinf(rotation) + center->x); + point->y = (int)(x * sinf(rotation) + y * cosf(rotation) + center->y); +} + +static void render_quads(QUAD *quads, int num_quads) +{ + gfx_quads_begin(); + float conv = 1/255.0f; + for(int i = 0; i < num_quads; i++) + { + QUAD *q = &quads[i]; + + gfx_quads_setsubset_free( + fx2f(q->texcoords[0].x), fx2f(q->texcoords[0].y), + fx2f(q->texcoords[1].x), fx2f(q->texcoords[1].y), + fx2f(q->texcoords[2].x), fx2f(q->texcoords[2].y), + fx2f(q->texcoords[3].x), fx2f(q->texcoords[3].y) + ); + + float r=1, g=1, b=1, a=1; + float offset_x = 0; + float offset_y = 0; + float rot = 0; + + if(editor.animate) + { + if(q->pos_env >= 0 && q->pos_env < editor.map.envelopes.len()) + { + ENVELOPE *e = editor.map.envelopes[q->pos_env]; + float t = editor.animate_time+q->pos_env_offset/1000.0f; + offset_x = e->eval(t, 0); + offset_y = e->eval(t, 1); + rot = e->eval(t, 2); + } + + if(q->color_env >= 0 && q->color_env < editor.map.envelopes.len()) + { + ENVELOPE *e = editor.map.envelopes[q->color_env]; + float t = editor.animate_time+q->color_env_offset/1000.0f; + r = e->eval(t, 0); + g = e->eval(t, 1); + b = e->eval(t, 2); + a = e->eval(t, 3); + } + } + + gfx_setcolorvertex(0, q->colors[0].r*conv*r, q->colors[0].g*conv*g, q->colors[0].b*conv*b, q->colors[0].a*conv*a); + gfx_setcolorvertex(1, q->colors[1].r*conv*r, q->colors[1].g*conv*g, q->colors[1].b*conv*b, q->colors[1].a*conv*a); + gfx_setcolorvertex(2, q->colors[2].r*conv*r, q->colors[2].g*conv*g, q->colors[2].b*conv*b, q->colors[2].a*conv*a); + gfx_setcolorvertex(3, q->colors[3].r*conv*r, q->colors[3].g*conv*g, q->colors[3].b*conv*b, q->colors[3].a*conv*a); + + POINT *points = q->points; + + if(rot != 0) + { + static POINT rotated[4]; + rotated[0] = q->points[0]; + rotated[1] = q->points[1]; + rotated[2] = q->points[2]; + rotated[3] = q->points[3]; + points = rotated; + + rotate(&q->points[4], &rotated[0], rot); + rotate(&q->points[4], &rotated[1], rot); + rotate(&q->points[4], &rotated[2], rot); + rotate(&q->points[4], &rotated[3], rot); + } + + gfx_quads_draw_freeform( + fx2f(points[0].x)+offset_x, fx2f(points[0].y)+offset_y, + fx2f(points[1].x)+offset_x, fx2f(points[1].y)+offset_y, + fx2f(points[2].x)+offset_x, fx2f(points[2].y)+offset_y, + fx2f(points[3].x)+offset_x, fx2f(points[3].y)+offset_y + ); + } + gfx_quads_end(); +} + +void LAYER_QUADS::render() +{ + gfx_texture_set(-1); + if(image >= 0 && image < editor.map.images.len()) + gfx_texture_set(editor.map.images[image]->tex_id); + + render_quads(quads.getptr(), quads.len()); +} + +QUAD *LAYER_QUADS::new_quad() +{ + QUAD *q = &quads[quads.add(QUAD())]; + + q->pos_env = -1; + q->color_env = -1; + q->pos_env_offset = 0; + q->color_env_offset = 0; + int x = 0, y = 0; + q->points[0].x = x; + q->points[0].y = y; + q->points[1].x = x+64; + q->points[1].y = y; + q->points[2].x = x; + q->points[2].y = y+64; + q->points[3].x = x+64; + q->points[3].y = y+64; + + q->points[4].x = x+32; // pivot + q->points[4].y = y+32; + + for(int i = 0; i < 5; i++) + { + q->points[i].x <<= 10; + q->points[i].y <<= 10; + } + + + q->texcoords[0].x = 0; + q->texcoords[0].y = 0; + + q->texcoords[1].x = 1<<10; + q->texcoords[1].y = 0; + + q->texcoords[2].x = 0; + q->texcoords[2].y = 1<<10; + + q->texcoords[3].x = 1<<10; + q->texcoords[3].y = 1<<10; + + q->colors[0].r = 255; q->colors[0].g = 255; q->colors[0].b = 255; q->colors[0].a = 255; + q->colors[1].r = 255; q->colors[1].g = 255; q->colors[1].b = 255; q->colors[1].a = 255; + q->colors[2].r = 255; q->colors[2].g = 255; q->colors[2].b = 255; q->colors[2].a = 255; + q->colors[3].r = 255; q->colors[3].g = 255; q->colors[3].b = 255; q->colors[3].a = 255; + + return q; +} + +void LAYER_QUADS::brush_selecting(RECT rect) +{ + // draw selection rectangle + gfx_texture_set(-1); + gfx_lines_begin(); + gfx_lines_draw(rect.x, rect.y, rect.x+rect.w, rect.y); + gfx_lines_draw(rect.x+rect.w, rect.y, rect.x+rect.w, rect.y+rect.h); + gfx_lines_draw(rect.x+rect.w, rect.y+rect.h, rect.x, rect.y+rect.h); + gfx_lines_draw(rect.x, rect.y+rect.h, rect.x, rect.y); + gfx_lines_end(); +} + +int LAYER_QUADS::brush_grab(LAYERGROUP *brush, RECT rect) +{ + // create new layers + LAYER_QUADS *grabbed = new LAYER_QUADS(); + grabbed->image = image; + brush->add_layer(grabbed); + + //dbg_msg("", "%f %f %f %f", rect.x, rect.y, rect.w, rect.h); + for(int i = 0; i < quads.len(); i++) + { + QUAD *q = &quads[i]; + float px = fx2f(q->points[4].x); + float py = fx2f(q->points[4].y); + + if(px > rect.x && px < rect.x+rect.w && py > rect.y && py < rect.y+rect.h) + { + dbg_msg("", "grabbed one"); + QUAD n; + n = *q; + + for(int p = 0; p < 5; p++) + { + n.points[p].x -= f2fx(rect.x); + n.points[p].y -= f2fx(rect.y); + } + + grabbed->quads.add(n); + } + } + + return grabbed->quads.len()?1:0; +} + +void LAYER_QUADS::brush_place(LAYER *brush, float wx, float wy) +{ + LAYER_QUADS *l = (LAYER_QUADS *)brush; + for(int i = 0; i < l->quads.len(); i++) + { + QUAD n = l->quads[i]; + + for(int p = 0; p < 5; p++) + { + n.points[p].x += f2fx(wx); + n.points[p].y += f2fx(wy); + } + + quads.add(n); + } +} + +void LAYER_QUADS::brush_flip_x() +{ +} + +void LAYER_QUADS::brush_flip_y() +{ +} + +void LAYER_QUADS::get_size(float *w, float *h) +{ + *w = 0; *h = 0; + + for(int i = 0; i < quads.len(); i++) + { + for(int p = 0; p < 5; p++) + { + *w = max(*w, fx2f(quads[i].points[p].x)); + *h = max(*h, fx2f(quads[i].points[p].y)); + } + } +} + +extern int selected_points; + +void LAYER_QUADS::render_properties(RECT *toolbox) +{ + // layer props + if(editor.props == PROPS_LAYER) + { + enum + { + PROP_IMAGE=0, + NUM_PROPS, + }; + + PROPERTY props[] = { + {"Image", image, PROPTYPE_INT_STEP, -1, 0}, + {0}, + }; + + static int ids[NUM_PROPS] = {0}; + int new_val = 0; + int prop = editor.do_properties(toolbox, props, ids, &new_val); + + if(prop == PROP_IMAGE) + { + if(new_val >= 0) + image = new_val%editor.map.images.len(); + else + image = -1; + } + } + + // quad props + QUAD *quad = editor.get_selected_quad(); + if(editor.props == PROPS_QUAD) + { + if(quad) + { + RECT slot; + ui_hsplit_t(toolbox, 15.0f, &slot, toolbox); + ui_do_label(&slot, "Quad Props", 12.0f, -1, -1); + + enum + { + PROP_POS_ENV=0, + PROP_POS_ENV_OFFSET, + PROP_COLOR_ENV, + PROP_COLOR_ENV_OFFSET, + NUM_PROPS, + }; + + PROPERTY props[] = { + {"Pos. Env", quad->pos_env, PROPTYPE_INT_STEP, -1, editor.map.envelopes.len()}, + {"Pos. TO", quad->pos_env_offset, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + {"Color Env", quad->color_env, PROPTYPE_INT_STEP, -1, editor.map.envelopes.len()}, + {"Color TO", quad->color_env_offset, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + + {0}, + }; + + static int ids[NUM_PROPS] = {0}; + int new_val = 0; + int prop = editor.do_properties(toolbox, props, ids, &new_val); + + if(prop == PROP_POS_ENV) quad->pos_env = new_val; + if(prop == PROP_POS_ENV_OFFSET) quad->pos_env_offset = new_val; + if(prop == PROP_COLOR_ENV) quad->color_env = new_val; + if(prop == PROP_COLOR_ENV_OFFSET) quad->color_env_offset = new_val; + } + } + + // point props + if(editor.props == PROPS_QUAD_POINT && quad && selected_points) + { + RECT slot; + ui_hsplit_t(toolbox, 15.0f, &slot, toolbox); + ui_do_label(&slot, "Point Props", 14.0f, -1, -1); + + enum + { + PROP_COLOR=0, + NUM_PROPS, + }; + + int color = 0; + + for(int v = 0; v < 4; v++) + { + if(selected_points&(1<<v)) + { + color = 0; + color |= quad->colors[v].r<<24; + color |= quad->colors[v].g<<16; + color |= quad->colors[v].b<<8; + color |= quad->colors[v].a; + } + } + + + PROPERTY props[] = { + {"Color", color, PROPTYPE_COLOR, -1, editor.map.envelopes.len()}, + {0}, + }; + + static int ids[NUM_PROPS] = {0}; + int new_val = 0; + int prop = editor.do_properties(toolbox, props, ids, &new_val); + if(prop == PROP_COLOR) + { + for(int v = 0; v < 4; v++) + { + if(selected_points&(1<<v)) + { + color = 0; + quad->colors[v].r = (new_val>>24)&0xff; + quad->colors[v].g = (new_val>>16)&0xff; + quad->colors[v].b = (new_val>>8)&0xff; + quad->colors[v].a = new_val&0xff; + } + } + } + } +} + + diff --git a/src/game/editor/ed_layer_tiles.cpp b/src/game/editor/ed_layer_tiles.cpp new file mode 100644 index 00000000..f697e56e --- /dev/null +++ b/src/game/editor/ed_layer_tiles.cpp @@ -0,0 +1,294 @@ +#include <game/client/gc_mapres_tilemap.h> +#include <game/g_math.h> +#include "editor.hpp" + +static void render_tilemap(TILE *tiles, int w, int h, float scale) +{ + //gfx_texture_set(img_get(tmap->image)); + float screen_x0, screen_y0, screen_x1, screen_y1; + gfx_getscreen(&screen_x0, &screen_y0, &screen_x1, &screen_y1); + + // calculate the final pixelsize for the tiles + float tile_pixelsize = 1024/32.0f; + float final_tilesize = scale/(screen_x1-screen_x0) * gfx_screenwidth(); + float final_tilesize_scale = final_tilesize/tile_pixelsize; + + gfx_quads_begin(); + + int starty = (int)(screen_y0/scale)-1; + int startx = (int)(screen_x0/scale)-1; + int endy = (int)(screen_y1/scale)+1; + int endx = (int)(screen_x1/scale)+1; + + // adjust the texture shift according to mipmap level + float texsize = 1024.0f; + float frac = (1.25f/texsize) * (1/final_tilesize_scale); + float nudge = (0.5f/texsize) * (1/final_tilesize_scale); + + for(int y = starty; y < endy; y++) + for(int x = startx; x < endx; x++) + { + int mx = x; + int my = y; + if(mx<0) + continue; // mx = 0; + if(mx>=w) + continue; // mx = w-1; + if(my<0) + continue; // my = 0; + if(my>=h) + continue; // my = h-1; + + int c = mx + my*w; + + unsigned char index = tiles[c].index; + if(index) + { + unsigned char flags = tiles[c].flags; + int tx = index%16; + int ty = index/16; + int px0 = tx*(1024/16); + int py0 = ty*(1024/16); + int px1 = (tx+1)*(1024/16)-1; + int py1 = (ty+1)*(1024/16)-1; + + float u0 = nudge + px0/texsize+frac; + float v0 = nudge + py0/texsize+frac; + float u1 = nudge + px1/texsize-frac; + float v1 = nudge + py1/texsize-frac; + + if(flags&TILEFLAG_VFLIP) + { + float tmp = u0; + u0 = u1; + u1 = tmp; + } + + if(flags&TILEFLAG_HFLIP) + { + float tmp = v0; + v0 = v1; + v1 = tmp; + } + + gfx_quads_setsubset(u0,v0,u1,v1); + + gfx_quads_drawTL(x*scale, y*scale, scale, scale); + } + } + + gfx_quads_end(); +} + +LAYER_TILES::LAYER_TILES(int w, int h) +{ + type = LAYERTYPE_TILES; + type_name = "Tiles"; + width = w; + height = h; + image = -1; + tex_id = -1; + game = 0; + + tiles = new TILE[width*height]; + mem_zero(tiles, width*height*sizeof(TILE)); +} + +LAYER_TILES::~LAYER_TILES() +{ + delete [] tiles; +} + +void LAYER_TILES::make_palette() +{ + for(int y = 0; y < height; y++) + for(int x = 0; x < width; x++) + tiles[y*width+x].index = y*16+x; +} + +void LAYER_TILES::render() +{ + if(image >= 0 && image < editor.map.images.len()) + tex_id = editor.map.images[image]->tex_id; + gfx_texture_set(tex_id); + render_tilemap(tiles, width, height, 32.0f); +} + +int LAYER_TILES::convert_x(float x) const { return (int)(x/32.0f); } +int LAYER_TILES::convert_y(float y) const { return (int)(y/32.0f); } + +void LAYER_TILES::convert(RECT rect, RECTi *out) +{ + out->x = convert_x(rect.x); + out->y = convert_y(rect.y); + out->w = convert_x(rect.x+rect.w+31) - out->x; + out->h = convert_y(rect.y+rect.h+31) - out->y; +} + +void LAYER_TILES::snap(RECT *rect) +{ + RECTi out; + convert(*rect, &out); + rect->x = out.x*32.0f; + rect->y = out.y*32.0f; + rect->w = out.w*32.0f; + rect->h = out.h*32.0f; +} + +void LAYER_TILES::clamp(RECTi *rect) +{ + if(rect->x < 0) + { + rect->w += rect->x; + rect->x = 0; + } + + if(rect->y < 0) + { + rect->h += rect->y; + rect->y = 0; + } + + if(rect->x+rect->w > width) + rect->w = width-rect->x; + + if(rect->y+rect->h > height) + rect->h = height-rect->y; + + if(rect->h < 0) + rect->h = 0; + if(rect->w < 0) + rect->w = 0; +} + +void LAYER_TILES::brush_selecting(RECT rect) +{ + gfx_texture_set(-1); + gfx_quads_begin(); + gfx_setcolor(1,1,1,0.4f); + snap(&rect); + gfx_quads_drawTL(rect.x, rect.y, rect.w, rect.h); + gfx_quads_end(); + +} + +int LAYER_TILES::brush_grab(LAYERGROUP *brush, RECT rect) +{ + RECTi r; + convert(rect, &r); + clamp(&r); + + if(!r.w || !r.h) + return 0; + + // create new layers + LAYER_TILES *grabbed = new LAYER_TILES(r.w, r.h); + grabbed->tex_id = tex_id; + grabbed->image = image; + brush->add_layer(grabbed); + + // copy the tiles + for(int y = 0; y < r.h; y++) + for(int x = 0; x < r.w; x++) + grabbed->tiles[y*grabbed->width+x] = tiles[(r.y+y)*width+(r.x+x)]; + + return 1; +} + +void LAYER_TILES::brush_draw(LAYER *brush, float wx, float wy) +{ + // + LAYER_TILES *l = (LAYER_TILES *)brush; + int sx = convert_x(wx); + int sy = convert_y(wy); + + for(int y = 0; y < l->height; y++) + for(int x = 0; x < l->width; x++) + { + int fx = x+sx; + int fy = y+sy; + if(fx<0 || fx >= width || fy < 0 || fy >= height) + continue; + + tiles[fy*width+fx] = l->tiles[y*l->width+x]; + } +} + +void LAYER_TILES::brush_flip_x() +{ + for(int y = 0; y < height; y++) + for(int x = 0; x < width/2; x++) + { + TILE tmp = tiles[y*width+x]; + tiles[y*width+x] = tiles[y*width+x+width-1-x]; + tiles[y*width+x+width-1-x] = tmp; + } + + for(int y = 0; y < height; y++) + for(int x = 0; x < width; x++) + tiles[y*width+x].flags ^= TILEFLAG_VFLIP; +} + +void LAYER_TILES::brush_flip_y() +{ + for(int y = 0; y < height/2; y++) + for(int x = 0; x < width; x++) + { + TILE tmp = tiles[y*width+x]; + tiles[y*width+x] = tiles[(height-1-y)*width+x]; + tiles[(height-1-y)*width+x] = tmp; + } + + for(int y = 0; y < height; y++) + for(int x = 0; x < width; x++) + tiles[y*width+x].flags ^= TILEFLAG_HFLIP; +} + +void LAYER_TILES::resize(int new_w, int new_h) +{ + TILE *new_data = new TILE[new_w*new_h]; + mem_zero(new_data, new_w*new_h*sizeof(TILE)); + + // copy old data + for(int y = 0; y < min(new_h, height); y++) + mem_copy(&new_data[y*new_w], &tiles[y*width], min(width, new_w)*sizeof(TILE)); + + // replace old + delete [] tiles; + tiles = new_data; + width = new_w; + height = new_h; +} + + +void LAYER_TILES::render_properties(RECT *toolbox) +{ + if(editor.props != PROPS_LAYER) + return; + + enum + { + PROP_IMAGE=0, + PROP_WIDTH, + PROP_HEIGHT, + NUM_PROPS, + }; + + PROPERTY props[] = { + {"Image", image, PROPTYPE_INT_STEP, 0, 0}, + {"Width", width, PROPTYPE_INT_STEP, 1, 1000000000}, + {"Height", height, PROPTYPE_INT_STEP, 1, 1000000000}, + {0}, + }; + + static int ids[NUM_PROPS] = {0}; + int new_val = 0; + int prop = editor.do_properties(toolbox, props, ids, &new_val); + + if(prop == PROP_IMAGE) + image = new_val%editor.map.images.len(); + else if(prop == PROP_WIDTH && new_val > 1) + resize(new_val, height); + else if(prop == PROP_HEIGHT && new_val > 1) + resize(width, new_val); +} diff --git a/src/game/editor/editor.cpp b/src/game/editor/editor.cpp new file mode 100644 index 00000000..5a9ebf45 --- /dev/null +++ b/src/game/editor/editor.cpp @@ -0,0 +1,2501 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +extern "C" { + #include <engine/e_system.h> + #include <engine/e_interface.h> + #include <engine/e_datafile.h> + #include <engine/e_config.h> +} + +#include <game/client/gc_mapres_image.h> +#include <game/client/gc_mapres_tilemap.h> +#include <game/client/gc_ui.h> +//#include "game/mapres_col.h" +#include <game/g_mapres.h> +#include <game/g_game.h> + +#include "editor.hpp" + +static int checker_texture = 0; +static int background_texture = 0; +static int cursor_texture = 0; +static int entities_texture = 0; + + +EDITOR editor; + +LAYERGROUP::LAYERGROUP() +{ + name = ""; + visible = true; + game_group = false; + offset_x = 0; + offset_y = 0; + parallax_x = 100; + parallax_y = 100; +} + +LAYERGROUP::~LAYERGROUP() +{ + clear(); +} + +void LAYERGROUP::convert(RECT *rect) +{ + rect->x += offset_x; + rect->y += offset_y; +} + +void LAYERGROUP::mapping(float *points) +{ + mapscreen_to_world( + editor.world_offset_x, editor.world_offset_y, + parallax_x/100.0f, parallax_y/100.0f, + offset_x, offset_y, + gfx_screenaspect(), editor.world_zoom, points); + + points[0] += editor.editor_offset_x; + points[1] += editor.editor_offset_y; + points[2] += editor.editor_offset_x; + points[3] += editor.editor_offset_y; +} + +void LAYERGROUP::mapscreen() +{ + float points[4]; + mapping(points); + gfx_mapscreen(points[0], points[1], points[2], points[3]); +} + +void LAYERGROUP::render() +{ + mapscreen(); + + for(int i = 0; i < layers.len(); i++) + { + if(layers[i]->visible && layers[i] != editor.game_layer) + layers[i]->render(); + } +} + +bool LAYERGROUP::is_empty() const { return layers.len() == 0; } +void LAYERGROUP::clear() { layers.deleteall(); } +void LAYERGROUP::add_layer(LAYER *l) { layers.add(l); } + +void LAYERGROUP::delete_layer(int index) +{ + if(index < 0 || index >= layers.len()) return; + delete layers[index]; + layers.removebyindex(index); +} + +void LAYERGROUP::get_size(float *w, float *h) +{ + *w = 0; *h = 0; + for(int i = 0; i < layers.len(); i++) + { + float lw, lh; + layers[i]->get_size(&lw, &lh); + *w = max(*w, lw); + *h = max(*h, lh); + } +} + + +int LAYERGROUP::swap_layers(int index0, int index1) +{ + if(index0 < 0 || index0 >= layers.len()) return index0; + if(index1 < 0 || index1 >= layers.len()) return index0; + if(index0 == index1) return index0; + swap(layers[index0], layers[index1]); + return index1; +} + +/******************************************************** + OTHER +*********************************************************/ +extern void draw_round_rect_ext(float x, float y, float w, float h, float r, int corners); +extern void draw_round_rect(float x, float y, float w, float h, float r); + +static void ui_draw_rect(const RECT *r, vec4 color, int corners, float rounding) +{ + gfx_texture_set(-1); + gfx_quads_begin(); + gfx_setcolor(color.r, color.g, color.b, color.a); + draw_round_rect_ext(r->x,r->y,r->w,r->h,rounding*ui_scale(), corners); + gfx_quads_end(); +} + +// copied from gc_menu.cpp, should be more generalized +extern int ui_do_edit_box(void *id, const RECT *rect, char *str, int str_size, bool hidden=false); + +static vec4 get_button_color(const void *id, int checked) +{ + if(checked < 0) + return vec4(0,0,0,0.5f); + + if(checked > 0) + { + if(ui_hot_item() == id) + return vec4(1,0,0,0.75f); + return vec4(1,0,0,0.5f); + } + + if(ui_hot_item() == id) + return vec4(1,1,1,0.75f); + return vec4(1,1,1,0.5f); +} + +static void draw_editor_button(const void *id, const char *text, int checked, const RECT *r, const void *extra) +{ + if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra; + ui_draw_rect(r, get_button_color(id, checked), CORNER_ALL, 5.0f); + ui_do_label(r, text, 10, 0, -1); +} + +static void draw_editor_button_l(const void *id, const char *text, int checked, const RECT *r, const void *extra) +{ + if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra; + ui_draw_rect(r, get_button_color(id, checked), CORNER_L, 5.0f); + ui_do_label(r, text, 10, 0, -1); +} + +static void draw_editor_button_m(const void *id, const char *text, int checked, const RECT *r, const void *extra) +{ + if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra; + ui_draw_rect(r, get_button_color(id, checked), 0, 5.0f); + ui_do_label(r, text, 10, 0, -1); +} + +static void draw_editor_button_r(const void *id, const char *text, int checked, const RECT *r, const void *extra) +{ + if(ui_hot_item() == id) if(extra) editor.tooltip = (const char *)extra; + ui_draw_rect(r, get_button_color(id, checked), CORNER_R, 5.0f); + ui_do_label(r, text, 10, 0, -1); +} + +static void draw_inc_button(const void *id, const char *text, int checked, const RECT *r, const void *extra) +{ + if(ui_hot_item == id) if(extra) editor.tooltip = (const char *)extra; + ui_draw_rect(r, get_button_color(id, checked), CORNER_R, 5.0f); + ui_do_label(r, ">", 10, 0, -1); +} + +static void draw_dec_button(const void *id, const char *text, int checked, const RECT *r, const void *extra) +{ + if(ui_hot_item == id) if(extra) editor.tooltip = (const char *)extra; + ui_draw_rect(r, get_button_color(id, checked), CORNER_L, 5.0f); + ui_do_label(r, "<", 10, 0, -1); +} + + + +static void render_background(RECT view, int texture, float size, float brightness) +{ + gfx_texture_set(texture); + gfx_blend_normal(); + gfx_quads_begin(); + gfx_setcolor(brightness,brightness,brightness,1.0f); + gfx_quads_setsubset(0,0, view.w/size, view.h/size); + gfx_quads_drawTL(view.x, view.y, view.w, view.h); + gfx_quads_end(); +} + + +static int selected_layer = 0; +static int selected_group = 0; +static int selected_quad = -1; +int selected_points = 0; +static int selected_envelope = 0; + +static LAYERGROUP brush; +static LAYER_TILES tileset_picker(16, 16); + +static int ui_do_value_selector(void *id, RECT *r, const char *label, int current, int min, int max, float scale) +{ + /* logic */ + static float value; + int ret = 0; + int inside = ui_mouse_inside(r); + + if(ui_active_item() == id) + { + if(!ui_mouse_button(0)) + { + if(inside) + ret = 1; + editor.lock_mouse = false; + ui_set_active_item(0); + } + else + { + if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT)) + value += editor.mouse_delta_x*0.05f; + else + value += editor.mouse_delta_x; + + if(fabs(value) > scale) + { + int count = (int)(value/scale); + value = fmod(value, scale); + current += count; + if(current < min) + current = min; + if(current > max) + current = max; + } + } + } + else if(ui_hot_item() == id) + { + if(ui_mouse_button(0)) + { + editor.lock_mouse = true; + value = 0; + ui_set_active_item(id); + } + } + + if(inside) + ui_set_hot_item(id); + + // render + char buf[128]; + sprintf(buf, "%s %d", label, current); + ui_draw_rect(r, get_button_color(id, 0), CORNER_ALL, 5.0f); + ui_do_label(r, buf, 12, 0, -1); + return current; +} + + +LAYERGROUP *EDITOR::get_selected_group() +{ + if(selected_group >= 0 && selected_group < editor.map.groups.len()) + return editor.map.groups[selected_group]; + return 0x0; +} + +LAYER *EDITOR::get_selected_layer(int index) +{ + LAYERGROUP *group = get_selected_group(); + if(!group) + return 0x0; + + if(selected_layer >= 0 && selected_layer < editor.map.groups[selected_group]->layers.len()) + return group->layers[selected_layer]; + return 0x0; +} + +LAYER *EDITOR::get_selected_layer_type(int index, int type) +{ + LAYER *p = get_selected_layer(index); + if(p && p->type == type) + return p; + return 0x0; +} + +QUAD *EDITOR::get_selected_quad() +{ + LAYER_QUADS *ql = (LAYER_QUADS *)get_selected_layer_type(0, LAYERTYPE_QUADS); + if(!ql) + return 0; + if(selected_quad >= 0 && selected_quad < ql->quads.len()) + return &ql->quads[selected_quad]; + return 0; +} + + +static void do_toolbar(RECT toolbar) +{ + RECT button; + + ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar); + static int zoom_out_button = 0; + if(ui_do_button(&zoom_out_button, "ZO", 0, &button, draw_editor_button_l, "[NumPad-] Zoom out") || inp_key_down(KEY_KP_SUBTRACT)) + editor.zoom_level += 50; + + ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar); + static int zoom_normal_button = 0; + if(ui_do_button(&zoom_normal_button, "1:1", 0, &button, draw_editor_button_m, "[NumPad*] Zoom to normal and remove editor offset") || inp_key_down(KEY_KP_MULTIPLY)) + { + editor.editor_offset_x = 0; + editor.editor_offset_y = 0; + editor.zoom_level = 100; + } + + ui_vsplit_l(&toolbar, 16.0f, &button, &toolbar); + static int zoom_in_button = 0; + if(ui_do_button(&zoom_in_button, "ZI", 0, &button, draw_editor_button_r, "[NumPad+] Zoom in") || inp_key_down(KEY_KP_ADD)) + editor.zoom_level -= 50; + + if(editor.zoom_level < 50) + editor.zoom_level = 50; + editor.world_zoom = editor.zoom_level/100.0f; + + ui_vsplit_l(&toolbar, 10.0f, &button, &toolbar); + + + // brush manipulation + { + int enabled = brush.is_empty()?-1:0; + + // flip buttons + ui_vsplit_l(&toolbar, 20.0f, &button, &toolbar); + static int flipx_button = 0; + if(ui_do_button(&flipx_button, "^X", enabled, &button, draw_editor_button_l, "Flip brush horizontal")) + { + for(int i = 0; i < brush.layers.len(); i++) + brush.layers[i]->brush_flip_x(); + } + + ui_vsplit_l(&toolbar, 20.0f, &button, &toolbar); + static int flipy_button = 0; + if(ui_do_button(&flipy_button, "^Y", enabled, &button, draw_editor_button_r, "Flip brush vertical")) + { + for(int i = 0; i < brush.layers.len(); i++) + brush.layers[i]->brush_flip_y(); + } + } + + // quad manipulation + { + // do add button + ui_vsplit_l(&toolbar, 10.0f, &button, &toolbar); + ui_vsplit_l(&toolbar, 60.0f, &button, &toolbar); + static int new_button = 0; + + LAYER_QUADS *qlayer = (LAYER_QUADS *)editor.get_selected_layer_type(0, LAYERTYPE_QUADS); + LAYER_TILES *tlayer = (LAYER_TILES *)editor.get_selected_layer_type(0, LAYERTYPE_TILES); + if(ui_do_button(&new_button, "Add Quad", qlayer?0:-1, &button, draw_editor_button, "Adds a new quad")) + { + if(qlayer) + { + float mapping[4]; + LAYERGROUP *g = editor.get_selected_group(); + g->mapping(mapping); + int add_x = f2fx(mapping[0] + (mapping[2]-mapping[0])/2); + int add_y = f2fx(mapping[1] + (mapping[3]-mapping[1])/2); + + QUAD *q = qlayer->new_quad(); + for(int i = 0; i < 5; i++) + { + q->points[i].x += add_x; + q->points[i].y += add_y; + } + } + } + + ui_vsplit_l(&toolbar, 10.0f, &button, &toolbar); + ui_vsplit_l(&toolbar, 60.0f, &button, &toolbar); + static int sq_button = 0; + if(ui_do_button(&sq_button, "Sq. Quad", editor.get_selected_quad()?0:-1, &button, draw_editor_button, "Squares the current quad")) + { + QUAD *q = editor.get_selected_quad(); + if(q) + { + int top = q->points[0].y; + int left = q->points[0].x; + int bottom = q->points[0].y; + int right = q->points[0].x; + + for(int k = 1; k < 4; k++) + { + if(q->points[k].y < top) top = q->points[k].y; + if(q->points[k].x < left) left = q->points[k].x; + if(q->points[k].y > bottom) bottom = q->points[k].y; + if(q->points[k].x > right) right = q->points[k].x; + } + + q->points[0].x = left; q->points[0].y = top; + q->points[1].x = right; q->points[1].y = top; + q->points[2].x = left; q->points[2].y = bottom; + q->points[3].x = right; q->points[3].y = bottom; + } + } + + ui_vsplit_l(&toolbar, 20.0f, &button, &toolbar); + ui_vsplit_l(&toolbar, 60.0f, &button, &toolbar); + bool in_gamegroup = editor.game_group->layers.find(tlayer) != -1; + static int col_button = 0; + if(ui_do_button(&col_button, "Make Col", (in_gamegroup&&tlayer)?0:-1, &button, draw_editor_button, "Constructs collision from the current layer")) + { + LAYER_TILES *gl = editor.game_layer; + int w = min(gl->width, tlayer->width); + int h = min(gl->height, tlayer->height); + dbg_msg("", "w=%d h=%d", w, h); + for(int y = 0; y < h; y++) + for(int x = 0; x < w; x++) + { + if(gl->tiles[y*gl->width+x].index <= TILE_SOLID) + gl->tiles[y*gl->width+x].index = tlayer->tiles[y*tlayer->width+x].index?TILE_SOLID:TILE_AIR; + } + } + } +} + +static void rotate(POINT *center, POINT *point, float rotation) +{ + int x = point->x - center->x; + int y = point->y - center->y; + point->x = (int)(x * cosf(rotation) - y * sinf(rotation) + center->x); + point->y = (int)(x * sinf(rotation) + y * cosf(rotation) + center->y); +} + +static void do_quad(QUAD *q, int index) +{ + enum + { + OP_NONE=0, + OP_MOVE_ALL, + OP_MOVE_PIVOT, + OP_ROTATE, + }; + + // some basic values + void *id = &q->points[4]; // use pivot addr as id + static POINT rotate_points[4]; + static float last_wx; + static float last_wy; + static int operation = OP_NONE; + static float rotate_angle = 0; + float wx = ui_mouse_world_x(); + float wy = ui_mouse_world_y(); + + // get pivot + float center_x = fx2f(q->points[4].x); + float center_y = fx2f(q->points[4].y); + + float dx = (center_x - wx); + float dy = (center_y - wy); + if(dx*dx+dy*dy < 10*10) + ui_set_hot_item(id); + + // draw selection background + if(selected_quad == index) + { + gfx_setcolor(0,0,0,1); + gfx_quads_draw(center_x, center_y, 7.0f, 7.0f); + } + + if(ui_active_item() == id) + { + // check if we only should move pivot + if(operation == OP_MOVE_PIVOT) + { + q->points[4].x += f2fx(wx-last_wx); + q->points[4].y += f2fx(wy-last_wy); + } + else if(operation == OP_MOVE_ALL) + { + // move all points including pivot + for(int v = 0; v < 5; v++) + { + q->points[v].x += f2fx(wx-last_wx); + q->points[v].y += f2fx(wy-last_wy); + } + } + else if(operation == OP_ROTATE) + { + for(int v = 0; v < 4; v++) + { + q->points[v] = rotate_points[v]; + rotate(&q->points[4], &q->points[v], rotate_angle); + } + } + + rotate_angle += (editor.mouse_delta_x) * 0.002f; + last_wx = wx; + last_wy = wy; + + if(!ui_mouse_button(0)) + { + editor.lock_mouse = false; + operation = OP_NONE; + ui_set_active_item(0); + } + + gfx_setcolor(1,1,1,1); + } + else if(ui_hot_item() == id) + { + gfx_setcolor(1,1,1,1); + editor.tooltip = "Left mouse button to move. Hold shift to move pivot. Hold ctrl to rotate"; + + if(ui_mouse_button(0)) + { + if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT)) + operation = OP_MOVE_PIVOT; + else if(inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL)) + { + editor.lock_mouse = true; + operation = OP_ROTATE; + rotate_angle = 0; + rotate_points[0] = q->points[0]; + rotate_points[1] = q->points[1]; + rotate_points[2] = q->points[2]; + rotate_points[3] = q->points[3]; + } + else + operation = OP_MOVE_ALL; + + ui_set_active_item(id); + selected_quad = index; + editor.props = PROPS_QUAD; + last_wx = wx; + last_wy = wy; + } + } + else + gfx_setcolor(0,1,0,1); + + gfx_quads_draw(center_x, center_y, 5.0f, 5.0f); +} + +static void do_quad_point(QUAD *q, int quad_index, int v) +{ + void *id = &q->points[v]; + + float wx = ui_mouse_world_x(); + float wy = ui_mouse_world_y(); + + float px = fx2f(q->points[v].x); + float py = fx2f(q->points[v].y); + + float dx = (px - wx); + float dy = (py - wy); + if(dx*dx+dy*dy < 10*10) + ui_set_hot_item(id); + + // draw selection background + if(selected_quad == quad_index && selected_points&(1<<v)) + { + gfx_setcolor(0,0,0,1); + gfx_quads_draw(px, py, 7.0f, 7.0f); + } + + enum + { + OP_NONE=0, + OP_MOVEPOINT, + OP_MOVEUV + }; + + static bool moved; + static int operation = OP_NONE; + + if(ui_active_item() == id) + { + float dx = editor.mouse_delta_wx; + float dy = editor.mouse_delta_wy; + if(!moved) + { + if(dx*dx+dy*dy > 0.5f) + moved = true; + } + + if(moved) + { + if(operation == OP_MOVEPOINT) + { + for(int m = 0; m < 4; m++) + if(selected_points&(1<<m)) + { + q->points[m].x += f2fx(dx); + q->points[m].y += f2fx(dy); + } + } + else if(operation == OP_MOVEUV) + { + for(int m = 0; m < 4; m++) + if(selected_points&(1<<m)) + { + q->texcoords[m].x += f2fx(dx*0.001f); + q->texcoords[m].y += f2fx(dy*0.001f); + } + } + } + + if(!ui_mouse_button(0)) + { + if(!moved) + { + if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT)) + selected_points ^= 1<<v; + else + selected_points = 1<<v; + + editor.props = PROPS_QUAD_POINT; + } + editor.lock_mouse = false; + ui_set_active_item(0); + } + + gfx_setcolor(1,1,1,1); + } + else if(ui_hot_item() == id) + { + gfx_setcolor(1,1,1,1); + editor.tooltip = "Left mouse button to move. Hold shift to move the texture."; + + if(ui_mouse_button(0)) + { + ui_set_active_item(id); + moved = false; + if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT)) + { + operation = OP_MOVEUV; + editor.lock_mouse = true; + } + else + operation = OP_MOVEPOINT; + + if(!(selected_points&(1<<v))) + { + if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT)) + selected_points |= 1<<v; + else + selected_points = 1<<v; + moved = true; + } + + editor.props = PROPS_QUAD_POINT; + selected_quad = quad_index; + } + } + else + gfx_setcolor(1,0,0,1); + + gfx_quads_draw(px, py, 5.0f, 5.0f); +} + +static void do_map_editor(RECT view, RECT toolbar) +{ + // do the toolbar + if(editor.gui_active) + do_toolbar(toolbar); + + ui_clip_enable(&view); + + bool show_picker = inp_key_pressed(KEY_SPACE) != 0; + + // render all good stuff + if(!show_picker) + { + for(int g = 0; g < editor.map.groups.len(); g++) + { + if(editor.map.groups[g]->visible) + editor.map.groups[g]->render(); + } + + // render the game above everything else + if(editor.game_group->visible && editor.game_layer->visible) + { + editor.game_group->mapscreen(); + editor.game_layer->render(); + } + } + + static void *editor_id = (void *)&editor_id; + int inside = ui_mouse_inside(&view); + + // fetch mouse position + float wx = ui_mouse_world_x(); + float wy = ui_mouse_world_y(); + float mx = ui_mouse_x(); + float my = ui_mouse_y(); + + static float start_wx = 0; + static float start_wy = 0; + static float start_mx = 0; + static float start_my = 0; + + enum + { + OP_NONE=0, + OP_BRUSH_GRAB, + OP_BRUSH_DRAW, + OP_PAN_WORLD, + OP_PAN_EDITOR, + }; + + // remap the screen so it can display the whole tileset + if(show_picker) + { + RECT screen = *ui_screen(); + float size = 32.0*16.0f; + float w = size*(screen.w/view.w); + float h = size*(screen.h/view.h); + float x = -(view.x/screen.w)*w; + float y = -(view.y/screen.h)*h; + wx = x+w*mx/screen.w; + wy = y+h*my/screen.h; + gfx_mapscreen(x, y, x+w, y+h); + LAYER_TILES *t = (LAYER_TILES *)editor.get_selected_layer_type(0, LAYERTYPE_TILES); + if(t) + { + tileset_picker.image = t->image; + tileset_picker.tex_id = t->tex_id; + tileset_picker.render(); + } + } + + static int operation = OP_NONE; + + // draw layer borders + LAYER *edit_layers[16]; + int num_edit_layers = 0; + num_edit_layers = 0; + + if(show_picker) + { + edit_layers[0] = &tileset_picker; + num_edit_layers++; + } + else + { + edit_layers[0] = editor.get_selected_layer(0); + if(edit_layers[0]) + num_edit_layers++; + + LAYERGROUP *g = editor.get_selected_group(); + if(g) + { + g->mapscreen(); + + for(int i = 0; i < num_edit_layers; i++) + { + if(edit_layers[i]->type != LAYERTYPE_TILES) + continue; + + float w, h; + edit_layers[i]->get_size(&w, &h); + + gfx_texture_set(-1); + gfx_lines_begin(); + gfx_lines_draw(0,0, w,0); + gfx_lines_draw(w,0, w,h); + gfx_lines_draw(w,h, 0,h); + gfx_lines_draw(0,h, 0,0); + gfx_lines_end(); + } + } + } + + if(inside) + { + ui_set_hot_item(editor_id); + + // do global operations like pan and zoom + if(ui_active_item() == 0 && ui_mouse_button(0)) + { + start_wx = wx; + start_wy = wy; + start_mx = mx; + start_my = my; + + if(inp_key_pressed(KEY_LALT)) + { + if(inp_key_pressed(KEY_LSHIFT)) + operation = OP_PAN_EDITOR; + else + operation = OP_PAN_WORLD; + ui_set_active_item(editor_id); + } + } + + // brush editing + { + if(brush.is_empty()) + editor.tooltip = "Use left mouse button to drag and create a brush."; + else + editor.tooltip = "Use left mouse button to paint with the brush. Right button clears the brush."; + + if(ui_active_item() == editor_id) + { + RECT r; + r.x = start_wx; + r.y = start_wy; + r.w = wx-start_wx; + r.h = wy-start_wy; + if(r.w < 0) + { + r.x += r.w; + r.w = -r.w; + } + + if(r.h < 0) + { + r.y += r.h; + r.h = -r.h; + } + + if(operation == OP_BRUSH_DRAW) + { + if(!brush.is_empty()) + { + // draw with brush + for(int k = 0; k < num_edit_layers; k++) + { + if(edit_layers[k]->type == brush.layers[0]->type) + edit_layers[k]->brush_draw(brush.layers[0], wx, wy); + } + } + } + else if(operation == OP_BRUSH_GRAB) + { + if(!ui_mouse_button(0)) + { + // grab brush + dbg_msg("editor", "grabbing %f %f %f %f", r.x, r.y, r.w, r.h); + + // TODO: do all layers + int grabs = 0; + for(int k = 0; k < num_edit_layers; k++) + grabs += edit_layers[k]->brush_grab(&brush, r); + if(grabs == 0) + brush.clear(); + } + else + { + editor.map.groups[selected_group]->mapscreen(); + for(int k = 0; k < num_edit_layers; k++) + edit_layers[k]->brush_selecting(r); + gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h); + } + } + } + else + { + if(ui_mouse_button(1)) + brush.clear(); + + if(ui_mouse_button(0) && operation == OP_NONE) + { + ui_set_active_item(editor_id); + + if(brush.is_empty()) + operation = OP_BRUSH_GRAB; + else + { + operation = OP_BRUSH_DRAW; + for(int k = 0; k < num_edit_layers; k++) + { + if(edit_layers[k]->type == brush.layers[0]->type) + edit_layers[k]->brush_place(brush.layers[0], wx, wy); + } + + } + } + + if(!brush.is_empty()) + { + brush.offset_x = -(int)wx; + brush.offset_y = -(int)wy; + for(int i = 0; i < brush.layers.len(); i++) + { + if(brush.layers[i]->type == LAYERTYPE_TILES) + { + brush.offset_x = -(int)(wx/32.0f)*32; + brush.offset_y = -(int)(wy/32.0f)*32; + break; + } + } + + LAYERGROUP *g = editor.get_selected_group(); + brush.offset_x += g->offset_x; + brush.offset_y += g->offset_y; + brush.parallax_x = g->parallax_x; + brush.parallax_y = g->parallax_y; + brush.render(); + float w, h; + brush.get_size(&w, &h); + + gfx_texture_set(-1); + gfx_lines_begin(); + gfx_lines_draw(0,0, w,0); + gfx_lines_draw(w,0, w,h); + gfx_lines_draw(w,h, 0,h); + gfx_lines_draw(0,h, 0,0); + gfx_lines_end(); + + } + } + } + + if(!show_picker && brush.is_empty()) + { + // fetch layers + LAYERGROUP *g = editor.get_selected_group(); + if(g) + g->mapscreen(); + + for(int k = 0; k < num_edit_layers; k++) + { + if(edit_layers[k]->type == LAYERTYPE_QUADS) + { + LAYER_QUADS *layer = (LAYER_QUADS *)edit_layers[k]; + + gfx_texture_set(-1); + gfx_quads_begin(); + for(int i = 0; i < layer->quads.len(); i++) + { + for(int v = 0; v < 4; v++) + do_quad_point(&layer->quads[i], i, v); + + do_quad(&layer->quads[i], i); + } + gfx_quads_end(); + } + } + + gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h); + } + + // do panning + if(ui_active_item() == editor_id) + { + if(operation == OP_PAN_WORLD) + { + editor.world_offset_x -= editor.mouse_delta_x*editor.world_zoom; + editor.world_offset_y -= editor.mouse_delta_y*editor.world_zoom; + } + else if(operation == OP_PAN_EDITOR) + { + editor.editor_offset_x -= editor.mouse_delta_x*editor.world_zoom; + editor.editor_offset_y -= editor.mouse_delta_y*editor.world_zoom; + } + } + + + // release mouse + if(!ui_mouse_button(0)) + { + operation = OP_NONE; + ui_set_active_item(0); + } + + } + + // render screen sizes + if(editor.proof_borders) + { + LAYERGROUP *g = editor.game_group; + g->mapscreen(); + + gfx_texture_set(-1); + gfx_lines_begin(); + + float last_points[4]; + float start = 1.0f; //9.0f/16.0f; + float end = 16.0f/9.0f; + const int num_steps = 20; + for(int i = 0; i <= num_steps; i++) + { + float points[4]; + float aspect = start + (end-start)*(i/(float)num_steps); + + mapscreen_to_world( + editor.world_offset_x, editor.world_offset_y, + 1.0f, 1.0f, 0.0f, 0.0f, aspect, 1.0f, points); + + if(i == 0) + { + gfx_lines_draw(points[0], points[1], points[2], points[1]); + gfx_lines_draw(points[0], points[3], points[2], points[3]); + } + + if(i != 0) + { + gfx_lines_draw(points[0], points[1], last_points[0], last_points[1]); + gfx_lines_draw(points[2], points[1], last_points[2], last_points[1]); + gfx_lines_draw(points[0], points[3], last_points[0], last_points[3]); + gfx_lines_draw(points[2], points[3], last_points[2], last_points[3]); + } + + if(i == num_steps) + { + gfx_lines_draw(points[0], points[1], points[0], points[3]); + gfx_lines_draw(points[2], points[1], points[2], points[3]); + } + + mem_copy(last_points, points, sizeof(points)); + } + + if(0) + { + gfx_setcolor(1.0f,0,0,1); + for(int i = 0; i < 4; i++) + { + float points[4]; + float aspects[] = {4.0f/3.0f, 5.0f/4.0f, 16.0f/10.0f, 16.0f/9.0f}; + float aspect = aspects[i]; + + mapscreen_to_world( + editor.world_offset_x, editor.world_offset_y, + 1.0f, 1.0f, 0.0f, 0.0f, aspect, 1.0f, points); + + RECT r; + r.x = points[0]; + r.y = points[1]; + r.w = points[2]-points[0]; + r.h = points[3]-points[1]; + + gfx_lines_draw(r.x, r.y, r.x+r.w, r.y); + gfx_lines_draw(r.x+r.w, r.y, r.x+r.w, r.y+r.h); + gfx_lines_draw(r.x+r.w, r.y+r.h, r.x, r.y+r.h); + gfx_lines_draw(r.x, r.y+r.h, r.x, r.y); + } + } + + gfx_lines_end(); + } + + gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h); + ui_clip_disable(); +} + +int EDITOR::do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val) +{ + int change = -1; + + for(int i = 0; props[i].name; i++) + { + RECT slot; + ui_hsplit_t(toolbox, 13.0f, &slot, toolbox); + RECT label, shifter; + ui_vsplit_mid(&slot, &label, &shifter); + ui_hmargin(&shifter, 1.0f, &shifter); + ui_do_label(&label, props[i].name, 10.0f, -1, -1); + + if(props[i].type == PROPTYPE_INT_STEP) + { + RECT inc, dec; + char buf[64]; + + ui_vsplit_r(&shifter, 10.0f, &shifter, &inc); + ui_vsplit_l(&shifter, 10.0f, &dec, &shifter); + sprintf(buf, "%d", props[i].value); + ui_draw_rect(&shifter, vec4(1,1,1,0.5f), 0, 0.0f); + ui_do_label(&shifter, buf, 10.0f, 0, -1); + + if(ui_do_button(&ids[i], 0, 0, &dec, draw_dec_button, "Decrease")) + { + if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT)) + *new_val = props[i].value-5; + else + *new_val = props[i].value-1; + change = i; + } + if(ui_do_button(((char *)&ids[i])+1, 0, 0, &inc, draw_inc_button, "Increase")) + { + if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT)) + *new_val = props[i].value+5; + else + *new_val = props[i].value+1; + change = i; + } + } + else if(props[i].type == PROPTYPE_INT_SCROLL) + { + int new_value = ui_do_value_selector(&ids[i], &shifter, "", props[i].value, props[i].min, props[i].max, 1.0f); + if(new_value != props[i].value) + { + *new_val = new_value; + change = i; + } + } + else if(props[i].type == PROPTYPE_COLOR) + { + static const char *texts[4] = {"R", "G", "B", "A"}; + static int shift[] = {24, 16, 8, 0}; + int new_color = 0; + + for(int c = 0; c < 4; c++) + { + int v = (props[i].value >> shift[c])&0xff; + new_color |= ui_do_value_selector(((char *)&ids[i])+c, &shifter, texts[c], v, 0, 255, 1.0f)<<shift[c]; + + if(c != 3) + { + ui_hsplit_t(toolbox, 13.0f, &slot, toolbox); + ui_vsplit_mid(&slot, 0, &shifter); + ui_hmargin(&shifter, 1.0f, &shifter); + } + } + + if(new_color != props[i].value) + { + *new_val = new_color; + change = i; + } + } + } + + return change; +} + +static void render_layers(RECT toolbox, RECT toolbar, RECT view) +{ + RECT layersbox = toolbox; + RECT propsbox; + + do_map_editor(view, toolbar); + + if(!editor.gui_active) + return; + + RECT slot, button; + char buf[64]; + + int valid_group = 0; + int valid_layer = 0; + if(selected_group >= 0 && selected_group < editor.map.groups.len()) + valid_group = 1; + + if(valid_group && selected_layer >= 0 && selected_layer < editor.map.groups[selected_group]->layers.len()) + valid_layer = 1; + + int valid_group_mask = valid_group ? 0 : -1; + int valid_layer_mask = valid_layer ? 0 : -1; + + { + ui_hsplit_t(&layersbox, 12.0f, &slot, &layersbox); + + // new layer group + ui_vsplit_l(&slot, 12.0f, &button, &slot); + static int new_layer_group_button = 0; + if(ui_do_button(&new_layer_group_button, "G+", 0, &button, draw_editor_button, "New group")) + { + editor.map.new_group(); + selected_group = editor.map.groups.len()-1; + editor.props = PROPS_GROUP; + } + + // new tile layer + ui_vsplit_l(&slot, 10.0f, &button, &slot); + ui_vsplit_l(&slot, 12.0f, &button, &slot); + static int new_tile_layer_button = 0; + if(ui_do_button(&new_tile_layer_button, "T+", valid_group_mask, &button, draw_editor_button, "New tile layer")) + { + LAYER *l = new LAYER_TILES(50, 50); + editor.map.groups[selected_group]->add_layer(l); + selected_layer = editor.map.groups[selected_group]->layers.len()-1; + editor.props = PROPS_LAYER; + } + + // new quad layer + ui_vsplit_l(&slot, 2.0f, &button, &slot); + ui_vsplit_l(&slot, 12.0f, &button, &slot); + static int new_quad_layer_button = 0; + if(ui_do_button(&new_quad_layer_button, "Q+", valid_group_mask, &button, draw_editor_button, "New quad layer")) + { + LAYER *l = new LAYER_QUADS; + editor.map.groups[selected_group]->add_layer(l); + selected_layer = editor.map.groups[selected_group]->layers.len()-1; + editor.props = PROPS_LAYER; + } + + // remove layer + ui_vsplit_r(&slot, 12.0f, &slot, &button); + static int delete_layer_button = 0; + if(ui_do_button(&delete_layer_button, "L-", valid_layer_mask, &button, draw_editor_button, "Delete layer")) + editor.map.groups[selected_group]->delete_layer(selected_layer); + + // remove group + ui_vsplit_r(&slot, 2.0f, &slot, &button); + ui_vsplit_r(&slot, 12.0f, &slot, &button); + static int delete_group_button = 0; + if(ui_do_button(&delete_group_button, "G-", valid_group_mask, &button, draw_editor_button, "Delete group")) + editor.map.delete_group(selected_group); + } + + ui_hsplit_t(&layersbox, 5.0f, &slot, &layersbox); + + // render layers + { + for(int g = 0; g < editor.map.groups.len(); g++) + { + RECT visible_toggle; + ui_hsplit_t(&layersbox, 12.0f, &slot, &layersbox); + ui_vsplit_l(&slot, 12, &visible_toggle, &slot); + if(ui_do_button(&editor.map.groups[g]->visible, editor.map.groups[g]->visible?"V":"H", 0, &visible_toggle, draw_editor_button_l, "Toggle group visibility")) + editor.map.groups[g]->visible = !editor.map.groups[g]->visible; + + sprintf(buf, "#%d %s", g, editor.map.groups[g]->name); + if(ui_do_button(&editor.map.groups[g], buf, g==selected_group, &slot, draw_editor_button_r, "Select group")) + { + selected_group = g; + selected_layer = 0; + editor.props = PROPS_GROUP; + } + + ui_hsplit_t(&layersbox, 2.0f, &slot, &layersbox); + + for(int i = 0; i < editor.map.groups[g]->layers.len(); i++) + { + //visible + ui_hsplit_t(&layersbox, 12.0f, &slot, &layersbox); + ui_vsplit_l(&slot, 12.0f, 0, &button); + ui_vsplit_l(&button, 15, &visible_toggle, &button); + + if(ui_do_button(&editor.map.groups[g]->layers[i]->visible, editor.map.groups[g]->layers[i]->visible?"V":"H", 0, &visible_toggle, draw_editor_button_l, "Toggle layer visibility")) + editor.map.groups[g]->layers[i]->visible = !editor.map.groups[g]->layers[i]->visible; + + sprintf(buf, "#%d %s ", i, editor.map.groups[g]->layers[i]->type_name); + if(ui_do_button(editor.map.groups[g]->layers[i], buf, g==selected_group&&i==selected_layer, &button, draw_editor_button_r, "Select layer")) + { + selected_layer = i; + selected_group = g; + editor.props = PROPS_LAYER; + } + ui_hsplit_t(&layersbox, 2.0f, &slot, &layersbox); + } + ui_hsplit_t(&layersbox, 5.0f, &slot, &layersbox); + } + } + + propsbox = layersbox; + + // group properties + if(editor.props == PROPS_GROUP && valid_group) + { + ui_hsplit_t(&propsbox, 12.0f, &slot, &propsbox); + ui_do_label(&slot, "Group Props", 12.0f, -1, -1); + + enum + { + PROP_ORDER=0, + PROP_POS_X, + PROP_POS_Y, + PROP_PARA_X, + PROP_PARA_Y, + NUM_PROPS, + }; + + PROPERTY props[] = { + {"Order", selected_group, PROPTYPE_INT_STEP, 0, editor.map.groups.len()-1}, + {"Pos X", -editor.map.groups[selected_group]->offset_x, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + {"Pos Y", -editor.map.groups[selected_group]->offset_y, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + {"Para X", editor.map.groups[selected_group]->parallax_x, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + {"Para Y", editor.map.groups[selected_group]->parallax_y, PROPTYPE_INT_SCROLL, -1000000, 1000000}, + {0}, + }; + + static int ids[NUM_PROPS] = {0}; + int new_val = 0; + + // cut the properties that isn't needed + if(editor.get_selected_group()->game_group) + props[PROP_POS_X].name = 0; + + int prop = editor.do_properties(&propsbox, props, ids, &new_val); + if(prop == PROP_ORDER) + selected_group = editor.map.swap_groups(selected_group, new_val); + + // these can not be changed on the game group + if(!editor.get_selected_group()->game_group) + { + if(prop == PROP_PARA_X) + editor.map.groups[selected_group]->parallax_x = new_val; + else if(prop == PROP_PARA_Y) + editor.map.groups[selected_group]->parallax_y = new_val; + else if(prop == PROP_POS_X) + editor.map.groups[selected_group]->offset_x = -new_val; + else if(prop == PROP_POS_Y) + editor.map.groups[selected_group]->offset_y = -new_val; + } + } + + // layer properties + if(editor.get_selected_layer(0)) + { + LAYERGROUP *current_group = editor.map.groups[selected_group]; + LAYER *current_layer = editor.get_selected_layer(0); + + if(editor.props == PROPS_LAYER) + { + ui_hsplit_t(&propsbox, 15.0f, &slot, &propsbox); + ui_do_label(&slot, "Layer Props", 12.0f, -1, -1); + + enum + { + PROP_GROUP=0, + PROP_ORDER, + NUM_PROPS, + }; + + PROPERTY props[] = { + {"Group", selected_group, PROPTYPE_INT_STEP, 0, editor.map.groups.len()-1}, + {"Order", selected_layer, PROPTYPE_INT_STEP, 0, current_group->layers.len()}, + {0}, + }; + + static int ids[NUM_PROPS] = {0}; + int new_val = 0; + int prop = editor.do_properties(&propsbox, props, ids, &new_val); + + if(prop == PROP_ORDER) + selected_layer = current_group->swap_layers(selected_layer, new_val); + else if(prop == PROP_GROUP && current_layer->type != LAYERTYPE_GAME) + { + if(new_val >= 0 && new_val < editor.map.groups.len()) + { + current_group->layers.remove(current_layer); + editor.map.groups[new_val]->layers.add(current_layer); + selected_group = new_val; + selected_layer = editor.map.groups[new_val]->layers.len()-1; + } + } + } + + current_layer->render_properties(&propsbox); + } +} + +static void render_images(RECT toolbox, RECT view) +{ + static int selected_image = 0; + + for(int i = 0; i < editor.map.images.len(); i++) + { + char buf[128]; + sprintf(buf, "#%d %dx%d", i, editor.map.images[i]->width, editor.map.images[i]->height); + RECT slot; + ui_hsplit_t(&toolbox, 15.0f, &slot, &toolbox); + + if(ui_do_button(&editor.map.images[i], buf, selected_image == i, &slot, draw_editor_button, "Select image")) + selected_image = i; + + ui_hsplit_t(&toolbox, 2.0f, 0, &toolbox); + + // render image + if(selected_image == i) + { + RECT r; + ui_margin(&view, 10.0f, &r); + if(r.h < r.w) + r.w = r.h; + else + r.h = r.w; + gfx_texture_set(editor.map.images[i]->tex_id); + gfx_blend_normal(); + gfx_quads_begin(); + gfx_quads_drawTL(r.x, r.y, r.w, r.h); + gfx_quads_end(); + + } + } + + RECT slot; + ui_hsplit_t(&toolbox, 5.0f, &slot, &toolbox); + ui_hsplit_t(&toolbox, 15.0f, &slot, &toolbox); + + // new image + static int new_image_button = 0; + if(ui_do_button(&new_image_button, "(Load New Image)", 0, &slot, draw_editor_button, "Load a new image to use in the map")) + editor.dialog = DIALOG_LOAD_IMAGE; + + ui_hsplit_t(&toolbox, 15.0f, &slot, &toolbox); +} + +static void editor_listdir_callback(const char *name, int is_dir, void *user) +{ + if(name[0] == '.') // skip this shit! + return; + + RECT *view = (RECT *)user; + RECT button; + ui_hsplit_t(view, 15.0f, &button, view); + ui_hsplit_t(view, 2.0f, 0, view); + + if(ui_do_button((void*)(10+(int)button.y), name, 0, &button, draw_editor_button, 0)) + { + char buf[512]; + sprintf(buf, "tilesets/%s", name); + + IMAGE imginfo; + if(!gfx_load_png(&imginfo, buf)) + return; + + IMAGE *img = new IMAGE; + *img = imginfo; + img->tex_id = gfx_load_texture_raw(imginfo.width, imginfo.height, imginfo.format, imginfo.data, IMG_AUTO); + editor.map.images.add(img); + + //tilesets_set_img(tilesets_new(), img.width, img.height, img.data); + editor.dialog = DIALOG_NONE; + } +} + +static void render_dialog_load_image() +{ + // GUI coordsys + gfx_clear(0.25f,0.25f,0.25f); + + gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h); + + RECT view = *ui_screen(); + fs_listdir("tilesets", editor_listdir_callback, &view); + + if(inp_key_pressed(KEY_ESC)) + editor.dialog = DIALOG_NONE; +} + +static void render_modebar(RECT view) +{ + RECT button; + + // mode buttons + { + ui_vsplit_l(&view, 40.0f, &button, &view); + static int map_button = 0; + if(ui_do_button(&map_button, "Map", editor.mode == MODE_MAP, &button, draw_editor_button_l, "Switch to edit global map settings")) + editor.mode = MODE_MAP; + + ui_vsplit_l(&view, 40.0f, &button, &view); + static int tile_button = 0; + if(ui_do_button(&tile_button, "Layers", editor.mode == MODE_LAYERS, &button, draw_editor_button_m, "Switch to edit layers")) + editor.mode = MODE_LAYERS; + + ui_vsplit_l(&view, 40.0f, &button, &view); + static int img_button = 0; + if(ui_do_button(&img_button, "Images", editor.mode == MODE_IMAGES, &button, draw_editor_button_r, "Switch to manage images")) + editor.mode = MODE_IMAGES; + } + + ui_vsplit_l(&view, 5.0f, 0, &view); + + // animate button + ui_vsplit_l(&view, 30.0f, &button, &view); + static int animate_button = 0; + if(ui_do_button(&animate_button, "Anim", editor.animate, &button, draw_editor_button, "[ctrl+m] Toggle animation") || + (inp_key_down('M') && (inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL)))) + { + editor.animate_start = time_get(); + editor.animate = !editor.animate; + } + + ui_vsplit_l(&view, 5.0f, 0, &view); + + // proof button + ui_vsplit_l(&view, 30.0f, &button, &view); + static int proof_button = 0; + if(ui_do_button(&proof_button, "Proof", editor.proof_borders, &button, draw_editor_button, "[ctrl-p] Toggles proof borders. These borders represent what a player maximum can see.") || + (inp_key_down('P') && (inp_key_pressed(KEY_LCTRL) || inp_key_pressed(KEY_RCTRL)))) + { + editor.proof_borders = !editor.proof_borders; + } + + // spacing + //ui_vsplit_l(&view, 10.0f, 0, &view); +} + +static void render_statusbar(RECT view) +{ + RECT button; + ui_vsplit_r(&view, 60.0f, &view, &button); + static int envelope_button = 0; + if(ui_do_button(&envelope_button, "Envelopes", editor.show_envelope_editor, &button, draw_editor_button, "Toggles the envelope editor")) + editor.show_envelope_editor = (editor.show_envelope_editor+1)%4; + + if(editor.tooltip) + ui_do_label(&view, editor.tooltip, 12.0f, -1, -1); +} + +static void render_envelopeeditor(RECT view) +{ + if(selected_envelope < 0) selected_envelope = 0; + if(selected_envelope >= editor.map.envelopes.len()) selected_envelope--; + + ENVELOPE *envelope = 0; + if(selected_envelope >= 0 && selected_envelope < editor.map.envelopes.len()) + envelope = editor.map.envelopes[selected_envelope]; + + bool show_colorbar = false; + if(envelope && envelope->channels == 4) + show_colorbar = true; + + RECT toolbar, curvebar, colorbar; + ui_hsplit_t(&view, 20.0f, &toolbar, &view); + ui_hsplit_t(&view, 20.0f, &curvebar, &view); + ui_margin(&toolbar, 2.0f, &toolbar); + ui_margin(&curvebar, 2.0f, &curvebar); + + if(show_colorbar) + { + ui_hsplit_t(&view, 20.0f, &colorbar, &view); + ui_margin(&colorbar, 2.0f, &colorbar); + render_background(colorbar, checker_texture, 16.0f, 1.0f); + } + + render_background(view, checker_texture, 32.0f, 0.1f); + + // do the toolbar + { + RECT button; + ENVELOPE *new_env = 0; + + ui_vsplit_r(&toolbar, 50.0f, &toolbar, &button); + static int new_4d_button = 0; + if(ui_do_button(&new_4d_button, "Color+", 0, &button, draw_editor_button, "Creates a new color envelope")) + new_env = editor.map.new_envelope(4); + + ui_vsplit_r(&toolbar, 5.0f, &toolbar, &button); + ui_vsplit_r(&toolbar, 50.0f, &toolbar, &button); + static int new_2d_button = 0; + if(ui_do_button(&new_2d_button, "Pos.+", 0, &button, draw_editor_button, "Creates a new pos envelope")) + new_env = editor.map.new_envelope(3); + + if(new_env) // add the default points + { + if(new_env->channels == 4) + { + new_env->add_point(0, 1,1,1,1); + new_env->add_point(1000, 1,1,1,1); + } + else + { + new_env->add_point(0, 0); + new_env->add_point(1000, 0); + } + } + + RECT shifter, inc, dec; + ui_vsplit_l(&toolbar, 60.0f, &shifter, &toolbar); + ui_vsplit_r(&shifter, 15.0f, &shifter, &inc); + ui_vsplit_l(&shifter, 15.0f, &dec, &shifter); + char buf[512]; + sprintf(buf, "%d/%d", selected_envelope+1, editor.map.envelopes.len()); + ui_draw_rect(&shifter, vec4(1,1,1,0.5f), 0, 0.0f); + ui_do_label(&shifter, buf, 14.0f, 0, -1); + + static int prev_button = 0; + if(ui_do_button(&prev_button, 0, 0, &dec, draw_dec_button, "Previous Envelope")) + selected_envelope--; + + static int next_button = 0; + if(ui_do_button(&next_button, 0, 0, &inc, draw_inc_button, "Next Envelope")) + selected_envelope++; + + if(envelope) + { + ui_vsplit_l(&toolbar, 15.0f, &button, &toolbar); + ui_vsplit_l(&toolbar, 35.0f, &button, &toolbar); + ui_do_label(&button, "Name:", 14.0f, -1, -1); + + ui_vsplit_l(&toolbar, 80.0f, &button, &toolbar); + static int name_box = 0; + ui_do_edit_box(&name_box, &button, envelope->name, sizeof(envelope->name)); + } + } + + if(envelope) + { + static array<int> selection; + static int envelope_editor_id = 0; + static int active_channels = 0xf; + + if(envelope) + { + RECT button; + + ui_vsplit_l(&toolbar, 15.0f, &button, &toolbar); + + static const char *names[4][4] = { + {"X", "", "", ""}, + {"X", "Y", "", ""}, + {"X", "Y", "R", ""}, + {"R", "G", "B", "A"}, + }; + + static int channel_buttons[4] = {0}; + int bit = 1; + ui_draw_button_func draw_func; + + for(int i = 0; i < envelope->channels; i++, bit<<=1) + { + ui_vsplit_l(&toolbar, 15.0f, &button, &toolbar); + + if(i == 0) draw_func = draw_editor_button_l; + else if(i == envelope->channels-1) draw_func = draw_editor_button_r; + else draw_func = draw_editor_button_m; + + if(ui_do_button(&channel_buttons[i], names[envelope->channels-1][i], active_channels&bit, &button, draw_func, 0)) + active_channels ^= bit; + } + } + + float end_time = envelope->end_time(); + if(end_time < 1) + end_time = 1; + + envelope->find_top_bottom(); + float top = envelope->top; + float bottom = envelope->bottom; + + if(top < 1) + top = 1; + if(bottom >= 0) + bottom = 0; + + float timescale = end_time/view.w; + float valuescale = (top-bottom)/view.h; + + if(ui_mouse_inside(&view)) + ui_set_hot_item(&envelope_editor_id); + + if(ui_hot_item() == &envelope_editor_id) + { + // do stuff + if(envelope) + { + if(ui_mouse_button_clicked(1)) + { + // add point + int time = (int)(((ui_mouse_x()-view.x)*timescale)*1000.0f); + //float env_y = (ui_mouse_y()-view.y)/timescale; + envelope->add_point(time, + f2fx(envelope->eval(time, 0)), + f2fx(envelope->eval(time, 1)), + f2fx(envelope->eval(time, 2)), + f2fx(envelope->eval(time, 3))); + } + + editor.tooltip = "Press right mouse button to create a new point"; + } + } + + vec3 colors[] = {vec3(1,0.2f,0.2f), vec3(0.2f,1,0.2f), vec3(0.2f,0.2f,1), vec3(1,1,0.2f)}; + + // render lines + { + gfx_texture_set(-1); + gfx_lines_begin(); + for(int c = 0; c < envelope->channels; c++) + { + if(active_channels&(1<<c)) + gfx_setcolor(colors[c].r,colors[c].g,colors[c].b,1); + else + gfx_setcolor(colors[c].r*0.5f,colors[c].g*0.5f,colors[c].b*0.5f,1); + + float prev_x = 0; + float prev_value = envelope->eval(0.000001f, c); + int steps = (int)((view.w/ui_screen()->w) * gfx_screenwidth()); + for(int i = 1; i <= steps; i++) + { + float a = i/(float)steps; + float v = envelope->eval(a*end_time, c); + v = (v-bottom)/(top-bottom); + + gfx_lines_draw(view.x + prev_x*view.w, view.y+view.h - prev_value*view.h, view.x + a*view.w, view.y+view.h - v*view.h); + prev_x = a; + prev_value = v; + } + } + gfx_lines_end(); + } + + // render curve options + { + for(int i = 0; i < envelope->points.len()-1; i++) + { + float t0 = envelope->points[i].time/1000.0f/end_time; + float t1 = envelope->points[i+1].time/1000.0f/end_time; + + //dbg_msg("", "%f", end_time); + + RECT v; + v.x = curvebar.x + (t0+(t1-t0)*0.5f) * curvebar.w; + v.y = curvebar.y; + v.h = curvebar.h; + v.w = curvebar.h; + v.x -= v.w/2; + void *id = &envelope->points[i].curvetype; + const char *type_name[] = { + "N", "L", "S", "F", "M" + }; + + if(ui_do_button(id, type_name[envelope->points[i].curvetype], 0, &v, draw_editor_button, "Switch curve type")) + envelope->points[i].curvetype = (envelope->points[i].curvetype+1)%NUM_CURVETYPES; + } + } + + // render colorbar + if(show_colorbar) + { + gfx_texture_set(-1); + gfx_quads_begin(); + for(int i = 0; i < envelope->points.len()-1; i++) + { + float r0 = fx2f(envelope->points[i].values[0]); + float g0 = fx2f(envelope->points[i].values[1]); + float b0 = fx2f(envelope->points[i].values[2]); + float a0 = fx2f(envelope->points[i].values[3]); + float r1 = fx2f(envelope->points[i+1].values[0]); + float g1 = fx2f(envelope->points[i+1].values[1]); + float b1 = fx2f(envelope->points[i+1].values[2]); + float a1 = fx2f(envelope->points[i+1].values[3]); + + gfx_setcolorvertex(0, r0, g0, b0, a0); + gfx_setcolorvertex(1, r1, g1, b1, a1); + gfx_setcolorvertex(2, r1, g1, b1, a1); + gfx_setcolorvertex(3, r0, g0, b0, a0); + + float x0 = envelope->points[i].time/1000.0f/end_time; +// float y0 = (fx2f(envelope->points[i].values[c])-bottom)/(top-bottom); + float x1 = envelope->points[i+1].time/1000.0f/end_time; + //float y1 = (fx2f(envelope->points[i+1].values[c])-bottom)/(top-bottom); + RECT v; + v.x = colorbar.x + x0*colorbar.w; + v.y = colorbar.y; + v.w = (x1-x0)*colorbar.w; + v.h = colorbar.h; + + gfx_quads_drawTL(v.x, v.y, v.w, v.h); + } + gfx_quads_end(); + } + + // render handles + { + static bool move = false; + + int current_value = 0, current_time = 0; + + gfx_texture_set(-1); + gfx_quads_begin(); + for(int c = 0; c < envelope->channels; c++) + { + if(!(active_channels&(1<<c))) + continue; + + for(int i = 0; i < envelope->points.len(); i++) + { + float x0 = envelope->points[i].time/1000.0f/end_time; + float y0 = (fx2f(envelope->points[i].values[c])-bottom)/(top-bottom); + RECT final; + final.x = view.x + x0*view.w; + final.y = view.y+view.h - y0*view.h; + final.x -= 2.0f; + final.y -= 2.0f; + final.w = 4.0f; + final.h = 4.0f; + + void *id = &envelope->points[i].values[c]; + + if(ui_mouse_inside(&final)) + ui_set_hot_item(id); + + float colormod = 1.0f; + + if(ui_active_item() == id) + { + if(!ui_mouse_button(0)) + { + ui_set_active_item(0); + move = false; + } + else + { + envelope->points[i].values[c] -= f2fx(editor.mouse_delta_y*valuescale); + if(inp_key_pressed(KEY_LSHIFT) || inp_key_pressed(KEY_RSHIFT)) + { + if(i != 0) + { + envelope->points[i].time += (int)((editor.mouse_delta_x*timescale)*1000.0f); + if(envelope->points[i].time < envelope->points[i-1].time) + envelope->points[i].time = envelope->points[i-1].time + 1; + if(i+1 != envelope->points.len() && envelope->points[i].time > envelope->points[i+1].time) + envelope->points[i].time = envelope->points[i+1].time - 1; + } + } + } + + colormod = 100.0f; + gfx_setcolor(1,1,1,1); + } + else if(ui_hot_item() == id) + { + if(ui_mouse_button(0)) + { + selection.clear(); + selection.add(i); + ui_set_active_item(id); + } + + // remove point + if(ui_mouse_button_clicked(1)) + envelope->points.removebyindex(i); + + colormod = 100.0f; + gfx_setcolor(1,0.75f,0.75f,1); + editor.tooltip = "Left mouse to drag. Hold shift to alter time point aswell. Right click to delete."; + } + + if(ui_active_item() == id || ui_hot_item() == id) + { + current_time = envelope->points[i].time; + current_value = envelope->points[i].values[c]; + } + + gfx_setcolor(colors[c].r*colormod, colors[c].g*colormod, colors[c].b*colormod, 1.0f); + gfx_quads_drawTL(final.x, final.y, final.w, final.h); + } + } + gfx_quads_end(); + + char buf[512]; + sprintf(buf, "%.3f %.3f", current_time/1000.0f, fx2f(current_value)); + ui_do_label(&toolbar, buf, 14.0f, 0, -1); + } + } +} + +static void editor_render() +{ + // basic start + gfx_clear(1.0f,0.0f,1.0f); + RECT view = *ui_screen(); + gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h); + + // reset tip + editor.tooltip = 0; + + // render checker + render_background(view, checker_texture, 32.0f, 1.0f); + + RECT modebar, toolbar, statusbar, envelope_editor, propsbar; + + if(editor.gui_active) + { + + ui_hsplit_t(&view, 16.0f, &toolbar, &view); + ui_vsplit_l(&view, 80.0f, &propsbar, &view); + ui_hsplit_b(&view, 16.0f, &view, &statusbar); + + + float brightness = 0.25f; + + render_background(propsbar, background_texture, 128.0f, brightness); + ui_margin(&propsbar, 2.0f, &propsbar); + + render_background(toolbar, background_texture, 128.0f, brightness); + ui_margin(&toolbar, 2.0f, &toolbar); + ui_vsplit_l(&toolbar, 220.0f, &modebar, &toolbar); + + render_background(statusbar, background_texture, 128.0f, brightness); + ui_margin(&statusbar, 2.0f, &statusbar); + + if(editor.show_envelope_editor) + { + float size = 125.0f; + if(editor.show_envelope_editor == 2) + size *= 2.0f; + else if(editor.show_envelope_editor == 3) + size *= 3.0f; + ui_hsplit_b(&view, size, &view, &envelope_editor); + render_background(envelope_editor, background_texture, 128.0f, brightness); + ui_margin(&envelope_editor, 2.0f, &envelope_editor); + } + } + + if(editor.dialog == DIALOG_LOAD_IMAGE) + render_dialog_load_image(); + else if(editor.mode == MODE_LAYERS) + render_layers(propsbar, toolbar, view); + else if(editor.mode == MODE_IMAGES) + render_images(propsbar, view); + + gfx_mapscreen(ui_screen()->x, ui_screen()->y, ui_screen()->w, ui_screen()->h); + + if(editor.gui_active) + { + render_modebar(modebar); + if(editor.show_envelope_editor) + render_envelopeeditor(envelope_editor); + render_statusbar(statusbar); + } + + //do_propsdialog(); + + // render butt ugly mouse cursor + float mx = ui_mouse_x(); + float my = ui_mouse_y(); + gfx_texture_set(cursor_texture); + gfx_quads_begin(); + gfx_quads_drawTL(mx,my, 16.0f, 16.0f); + gfx_quads_end(); +} + +void editor_reset(bool create_default=true) +{ + editor.map.groups.deleteall(); + editor.map.envelopes.deleteall(); + editor.map.images.deleteall(); + + editor.game_layer = 0; + editor.game_group = 0; + + // create default layers + if(create_default) + { + editor.make_game_group(editor.map.new_group()); + editor.make_game_layer(new LAYER_GAME(50, 50)); + editor.game_group->add_layer(editor.game_layer); + } +} + +void EDITOR::make_game_layer(LAYER *layer) +{ + editor.game_layer = (LAYER_GAME *)layer; + editor.game_layer->tex_id = entities_texture; + editor.game_layer->readonly = true; +} + +void EDITOR::make_game_group(LAYERGROUP *group) +{ + editor.game_group = group; + editor.game_group->game_group = true; + editor.game_group->name = "Game"; +} + +typedef struct +{ + int version; + int width; + int height; + int external; + int image_name; + int image_data; +} MAPITEM_IMAGE; + +typedef struct +{ + int version; + int offset_x; + int offset_y; + int parallax_x; + int parallax_y; + + int start_layer; + int num_layers; +} MAPITEM_GROUP; + +typedef struct +{ + int version; + int type; + int flags; +} MAPITEM_LAYER; + +typedef struct +{ + MAPITEM_LAYER layer; + int version; + + int width; + int height; + int flags; + + COLOR color; + int color_env; + int color_env_offset; + + int image; + int data; +} MAPITEM_LAYER_TILEMAP; + +typedef struct +{ + MAPITEM_LAYER layer; + int version; + + int num_quads; + int data; + int image; +} MAPITEM_LAYER_QUADS; + +typedef struct +{ + int version; +} MAPITEM_VERSION; + +template<typename T> +static int make_version(int i, const T &v) +{ return (i<<16)+sizeof(T); } + +enum +{ + MAPITEMTYPE_VERSION=0, + MAPITEMTYPE_INFO, + MAPITEMTYPE_IMAGE, + MAPITEMTYPE_ENVELOPE, + MAPITEMTYPE_GROUP, + MAPITEMTYPE_LAYER, +}; + + +void editor_load_old(DATAFILE *df) +{ + // load tilemaps + int game_width = 0; + int game_height = 0; + { + 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); + + LAYER_TILES *l = new LAYER_TILES(tmap->width, tmap->height); + + if(tmap->main) + { + // move game layer to correct position + for(int i = 0; i < editor.map.groups[0]->layers.len()-1; i++) + { + if(editor.map.groups[0]->layers[i] == editor.game_layer) + editor.map.groups[0]->swap_layers(i, i+1); + } + + game_width = tmap->width; + game_height = tmap->height; + } + + // add new layer + editor.map.groups[0]->add_layer(l); + + // process the data + unsigned char *src_data = (unsigned char *)datafile_get_data(df, tmap->data); + TILE *dst_data = l->tiles; + + for(int y = 0; y < tmap->height; y++) + for(int x = 0; x < tmap->width; x++, dst_data++, src_data+=2) + { + dst_data->index = src_data[0]; + dst_data->flags = src_data[1]; + } + + l->image = tmap->image; + } + } + + // load images + { + int start, count; + datafile_get_type(df, MAPRES_IMAGE, &start, &count); + for(int i = 0; i < count; i++) + { + mapres_image *imgres = (mapres_image *)datafile_get_item(df, start+i, 0, 0); + void *data = datafile_get_data(df, imgres->image_data); + + IMAGE *img = new IMAGE; + img->width = imgres->width; + img->height = imgres->height; + img->format = IMG_RGBA; + + // copy image data + img->data = mem_alloc(img->width*img->height*4, 1); + mem_copy(img->data, data, img->width*img->height*4); + img->tex_id = gfx_load_texture_raw(img->width, img->height, img->format, img->data, IMG_AUTO); + editor.map.images.add(img); + + // unload image + datafile_unload_data(df, imgres->image_data); + } + } + + // load entities + { + LAYER_GAME *g = editor.game_layer; + g->resize(game_width, game_height); + 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); + int x = e->x/32; + int y = e->y/32; + int id = -1; + + if(t == MAPRES_SPAWNPOINT) id = ENTITY_SPAWN; + else if(t == MAPRES_SPAWNPOINT_RED) id = ENTITY_SPAWN_RED; + else if(t == MAPRES_SPAWNPOINT_BLUE) id = ENTITY_SPAWN_BLUE; + else if(t == MAPRES_FLAGSTAND_RED) id = ENTITY_FLAGSTAND_RED; + else if(t == MAPRES_FLAGSTAND_BLUE) id = ENTITY_FLAGSTAND_BLUE; + else if(t == MAPRES_ITEM) + { + if(e->data[0] == ITEM_WEAPON_SHOTGUN) id = ENTITY_WEAPON_SHOTGUN; + else if(e->data[0] == ITEM_WEAPON_ROCKET) id = ENTITY_WEAPON_ROCKET; + else if(e->data[0] == ITEM_NINJA) id = ENTITY_POWERUP_NINJA; + else if(e->data[0] == ITEM_ARMOR) id = ENTITY_ARMOR_1; + else if(e->data[0] == ITEM_HEALTH) id = ENTITY_HEATH_1; + } + + if(id > 0 && x >= 0 && x < g->width && y >= 0 && y < g->height) + g->tiles[y*g->width+x].index = id; + } + } + } +} + +int EDITOR::save(const char *filename) +{ + dbg_msg("editor", "saving to '%s'...", filename); + DATAFILE_OUT *df = datafile_create(filename); + if(!df) + { + dbg_msg("editor", "failed to open file '%s'...", filename); + return 0; + } + + // save version + { + MAPITEM_VERSION item; + item.version = 1; + datafile_add_item(df, MAPITEMTYPE_VERSION, 0, sizeof(item), &item); + } + + // save images + for(int i = 0; i < map.images.len(); i++) + { + IMAGE *img = map.images[i]; + MAPITEM_IMAGE item; + item.version = 1; + + item.width = img->width; + item.height = img->height; + item.external = 0; + item.image_name = -1; + item.image_data = datafile_add_data(df, item.width*item.height*4, img->data); + datafile_add_item(df, MAPITEMTYPE_IMAGE, i, sizeof(item), &item); + } + + // save layers + int layer_count = 0; + for(int g = 0; g < map.groups.len(); g++) + { + LAYERGROUP *group = map.groups[g]; + MAPITEM_GROUP gitem; + gitem.version = 1; + + gitem.parallax_x = group->parallax_x; + gitem.parallax_y = group->parallax_y; + gitem.offset_x = group->offset_x; + gitem.offset_y = group->offset_y; + gitem.start_layer = layer_count; + gitem.num_layers = 0; + + for(int l = 0; l < group->layers.len(); l++) + { + if(group->layers[l]->type == LAYERTYPE_TILES) + { + dbg_msg("editor", "saving tiles layer"); + LAYER_TILES *layer = (LAYER_TILES *)group->layers[l]; + MAPITEM_LAYER_TILEMAP item; + item.version = 2; + + item.layer.flags = 0; + item.layer.type = layer->type; + + item.color.r = 255; // not in use right now + item.color.g = 255; + item.color.b = 255; + item.color.a = 255; + item.color_env = -1; + item.color_env_offset = 0; + + item.width = layer->width; + item.height = layer->height; + item.flags = layer->game; + item.image = layer->image; + item.data = datafile_add_data(df, layer->width*layer->height*sizeof(TILE), layer->tiles); + datafile_add_item(df, MAPITEMTYPE_LAYER, layer_count, sizeof(item), &item); + + gitem.num_layers++; + layer_count++; + } + else if(group->layers[l]->type == LAYERTYPE_QUADS) + { + dbg_msg("editor", "saving quads layer"); + LAYER_QUADS *layer = (LAYER_QUADS *)group->layers[l]; + if(layer->quads.len()) + { + MAPITEM_LAYER_QUADS item; + item.version = 1; + item.layer.flags = 0; + item.layer.type = layer->type; + item.image = layer->image; + + // add the data + item.num_quads = layer->quads.len(); + item.data = datafile_add_data_swapped(df, layer->quads.len()*sizeof(QUAD), layer->quads.getptr()); + datafile_add_item(df, MAPITEMTYPE_LAYER, layer_count, sizeof(item), &item); + + // clean up + //mem_free(quads); + + gitem.num_layers++; + layer_count++; + } + } + } + + datafile_add_item(df, MAPITEMTYPE_GROUP, g, sizeof(gitem), &gitem); + } + + // finish the data file + datafile_finish(df); + dbg_msg("editor", "done"); + return 1; +} + + +int EDITOR::load(const char *filename) +{ + DATAFILE *df = datafile_load(filename); + if(!df) + return 0; + + // check version + MAPITEM_VERSION *item = (MAPITEM_VERSION *)datafile_find_item(df, MAPITEMTYPE_VERSION, 0); + if(!item) + { + // import old map + editor_reset(); + editor_load_old(df); + } + else if(item->version == 1) + { + editor_reset(false); + + // load images + { + int start, num; + datafile_get_type(df, MAPITEMTYPE_IMAGE, &start, &num); + for(int i = 0; i < num; i++) + { + MAPITEM_IMAGE *item = (MAPITEM_IMAGE *)datafile_get_item(df, start+i, 0, 0); + void *data = datafile_get_data(df, item->image_data); + + IMAGE *img = new IMAGE; + img->width = item->width; + img->height = item->height; + img->format = IMG_RGBA; + + // copy image data + img->data = mem_alloc(img->width*img->height*4, 1); + mem_copy(img->data, data, img->width*img->height*4); + img->tex_id = gfx_load_texture_raw(img->width, img->height, img->format, img->data, IMG_AUTO); + editor.map.images.add(img); + + // unload image + datafile_unload_data(df, item->image_data); + } + } + + // load groups + { + int layers_start, layers_num; + datafile_get_type(df, MAPITEMTYPE_LAYER, &layers_start, &layers_num); + + int start, num; + datafile_get_type(df, MAPITEMTYPE_GROUP, &start, &num); + for(int g = 0; g < num; g++) + { + MAPITEM_GROUP *gitem = (MAPITEM_GROUP *)datafile_get_item(df, start+g, 0, 0); + LAYERGROUP *group = map.new_group(); + group->parallax_x = gitem->parallax_x; + group->parallax_y = gitem->parallax_y; + group->offset_x = gitem->offset_x; + group->offset_y = gitem->offset_y; + + for(int l = 0; l < gitem->num_layers; l++) + { + MAPITEM_LAYER *layer_item = (MAPITEM_LAYER *)datafile_get_item(df, layers_start+gitem->start_layer+l, 0, 0); + if(!layer_item) + continue; + + if(layer_item->type == LAYERTYPE_TILES) + { + MAPITEM_LAYER_TILEMAP *tilemap_item = (MAPITEM_LAYER_TILEMAP *)layer_item; + LAYER_TILES *tiles = 0; + + if(tilemap_item->flags&1) + { + tiles = new LAYER_GAME(tilemap_item->width, tilemap_item->height); + editor.make_game_layer(tiles); + make_game_group(group); + } + else + tiles = new LAYER_TILES(tilemap_item->width, tilemap_item->height); + + group->add_layer(tiles); + void *data = datafile_get_data(df, tilemap_item->data); + tiles->image = tilemap_item->image; + tiles->game = tilemap_item->flags&1; + + mem_copy(tiles->tiles, data, tiles->width*tiles->height*sizeof(TILE)); + + if(tiles->game && tilemap_item->version == make_version(1, *tilemap_item)) + { + for(int i = 0; i < tiles->width*tiles->height; i++) + { + if(tiles->tiles[i].index) + tiles->tiles[i].index += ENTITY_OFFSET; + } + } + + datafile_unload_data(df, tilemap_item->data); + } + else if(layer_item->type == LAYERTYPE_QUADS) + { + MAPITEM_LAYER_QUADS *quads_item = (MAPITEM_LAYER_QUADS *)layer_item; + LAYER_QUADS *layer = new LAYER_QUADS; + layer->image = quads_item->image; + if(layer->image < -1 || layer->image >= map.images.len()) + layer->image = -1; + void *data = datafile_get_data_swapped(df, quads_item->data); + group->add_layer(layer); + layer->quads.setsize(quads_item->num_quads); + mem_copy(layer->quads.getptr(), data, sizeof(QUAD)*quads_item->num_quads); + datafile_unload_data(df, quads_item->data); + } + } + } + } + } + + datafile_unload(df); + + return 0; +} + + +extern "C" void editor_init() +{ + checker_texture = gfx_load_texture("data/editor/checker.png", IMG_AUTO); + background_texture = gfx_load_texture("data/editor/background.png", IMG_AUTO); + cursor_texture = gfx_load_texture("data/editor/cursor.png", IMG_AUTO); + entities_texture = gfx_load_texture("data/editor/entities.png", IMG_AUTO); + + tileset_picker.make_palette(); + tileset_picker.readonly = true; + + editor_reset(); + //editor.load("debug_test.map"); + +#if 0 + IMAGE *img = new IMAGE; + gfx_load_png(img, "tilesets/grassland_main.png"); + img->tex_id = gfx_load_texture_raw(img->width, img->height, img->format, img->data); + editor.map.images.add(img); + + + ENVELOPE *e = editor.map.new_envelope(4); + e->add_point(0, 0, 0); + e->add_point(1000, f2fx(1), f2fx(0.75f)); + e->add_point(2000, f2fx(0.75f), f2fx(1)); + e->add_point(3000, 0, 0); + + editor.animate = true; + editor.animate_start = time_get(); + + editor.show_envelope_editor = 1; +#endif + + if(1) + { + float w, h; + float amount = 1300*1000; + float max = 1500; + dbg_msg("", "%f %f %f %f", (900*(5/4.0f))*900.0f, (900*(4/3.0f))*900.0f, (900*(16/9.0f))*900.0f, (900*(16/10.0f))*900.0f); + dbg_msg("", "%f", 900*(16/9.0f)); + calc_screen_params(amount, max, max, 5.0f/4.0f, &w, &h); dbg_msg("", "5:4 %f %f %f", w, h, w*h); + calc_screen_params(amount, max, max, 4.0f/3.0f, &w, &h); dbg_msg("", "4:3 %f %f %f", w, h, w*h); + calc_screen_params(amount, max, max, 16.0f/9.0f, &w, &h); dbg_msg("", "16:9 %f %f %f", w, h, w*h); + calc_screen_params(amount, max, max, 16.0f/10.0f, &w, &h); dbg_msg("", "16:10 %f %f %f", w, h, w*h); + + calc_screen_params(amount, max, max, 9.0f/16.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h); + calc_screen_params(amount, max, max, 16.0f/3.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h); + calc_screen_params(amount, max, max, 3.0f/16.0f, &w, &h); dbg_msg("", "%f %f %f", w, h, w*h); + } +} + +extern "C" void editor_update_and_render() +{ + static int mouse_x = 0; + static int mouse_y = 0; + + editor.animate_time = (time_get()-editor.animate_start)/(float)time_freq(); + + // handle mouse movement + float mx, my, mwx, mwy; + int rx, ry; + { + inp_mouse_relative(&rx, &ry); + editor.mouse_delta_x = rx; + editor.mouse_delta_y = ry; + + if(!editor.lock_mouse) + { + mouse_x += rx; + mouse_y += ry; + } + + if(mouse_x < 0) mouse_x = 0; + if(mouse_y < 0) mouse_y = 0; + if(mouse_x > ui_screen()->w) mouse_x = (int)ui_screen()->w; + if(mouse_y > ui_screen()->h) mouse_y = (int)ui_screen()->h; + + // update the ui + mx = mouse_x; + my = mouse_y; + mwx = 0; + mwy = 0; + + // fix correct world x and y + LAYERGROUP *g = editor.get_selected_group(); + if(g) + { + float points[4]; + g->mapping(points); + + float world_width = points[2]-points[0]; + float world_height = points[3]-points[1]; + + mwx = points[0] + world_width * (mouse_x/ui_screen()->w); + mwy = points[1] + world_height * (mouse_y/ui_screen()->h); + editor.mouse_delta_wx = editor.mouse_delta_x*(world_width / ui_screen()->w); + editor.mouse_delta_wy = editor.mouse_delta_y*(world_height / ui_screen()->h); + } + + 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); + } + + // toggle gui + if(inp_key_down(KEY_TAB)) + editor.gui_active = !editor.gui_active; + + if(inp_key_down(KEY_F5)) + editor.save("data/maps/debug_test2.map"); + + if(inp_key_down(KEY_F8)) + editor.load("data/maps/debug_test.map"); + + editor_render(); + inp_clear_events(); +} + diff --git a/src/game/editor/editor.hpp b/src/game/editor/editor.hpp new file mode 100644 index 00000000..0d2af5e1 --- /dev/null +++ b/src/game/editor/editor.hpp @@ -0,0 +1,569 @@ +#include <stdlib.h> +#include <math.h> +#include "array.h" + +extern "C" { + #include <engine/e_system.h> + #include <engine/e_interface.h> + #include <engine/e_datafile.h> + #include <engine/e_config.h> +} + +#include <game/client/gc_ui.h> + +// EDITOR SPECIFIC +template<typename T> +void swap(T &a, T &b) +{ + T tmp = a; + a = b; + b = tmp; +} + +enum +{ + MODE_MAP=0, + MODE_LAYERS, + MODE_IMAGES, + + DIALOG_NONE=0, + DIALOG_LOAD_IMAGE, + + LAYERTYPE_INVALID=0, + LAYERTYPE_GAME, + LAYERTYPE_TILES, + LAYERTYPE_QUADS, +}; + +typedef struct +{ + int x, y; // 22.10 fixed point +} POINT; + +// float to fixed +inline int f2fx(float v) { return (int)(v*(float)(1<<10)); } +inline float fx2f(int v) { return v*(1.0f/(1<<10)); } + +typedef struct // as in file +{ + int r, g, b, a; +} COLOR; + +typedef struct // as in file +{ + POINT points[5]; + COLOR colors[4]; + POINT texcoords[4]; + + int pos_env; + int pos_env_offset; + + int color_env; + int color_env_offset; +} QUAD; + +typedef struct // as in file +{ + POINT position; + int type; +} ENTITY; + +enum +{ + ENTITY_NULL=0, + ENTITY_SPAWN, + ENTITY_SPAWN_RED, + ENTITY_SPAWN_BLUE, + ENTITY_FLAGSTAND_RED, + ENTITY_FLAGSTAND_BLUE, + ENTITY_ARMOR_1, + ENTITY_HEATH_1, + ENTITY_WEAPON_SHOTGUN, + ENTITY_WEAPON_ROCKET, + ENTITY_POWERUP_NINJA, + NUM_ENTITIES, + + TILE_AIR=0, + TILE_SOLID, + TILE_NOHOOK, + + ENTITY_OFFSET=255-16*4, +}; + +typedef struct // as in file +{ + unsigned char index; + unsigned char flags; + unsigned char reserved1; + unsigned char reserved2; +} TILE; + +enum +{ + CURVETYPE_STEP=0, + CURVETYPE_LINEAR, + CURVETYPE_SLOW, + CURVETYPE_FAST, + CURVETYPE_SMOOTH, + NUM_CURVETYPES, + +}; + +typedef struct // as in file +{ + int time; // in ms + int curvetype; + int values[4]; // 1-4 depending on envelope (22.10 fixed point) +} ENVPOINT; + +class ENVELOPE +{ +public: + int channels; + array<ENVPOINT> points; + char name[32]; + float bottom, top; + + ENVELOPE(int chan) + { + channels = chan; + name[0] = 0; + bottom = 0; + top = 0; + } + + static int sort_comp(const void *v0, const void *v1) + { + const ENVPOINT *p0 = (const ENVPOINT *)v0; + const ENVPOINT *p1 = (const ENVPOINT *)v1; + if(p0->time < p1->time) + return -1; + if(p0->time > p1->time) + return 1; + return 0; + } + + void resort() + { + qsort(points.getptr(), points.len(), sizeof(ENVPOINT), sort_comp); + find_top_bottom(); + } + + void find_top_bottom() + { + top = -1000000000.0f; + bottom = 1000000000.0f; + for(int i = 0; i < points.len(); i++) + { + for(int c = 0; c < channels; c++) + { + float v = fx2f(points[i].values[c]); + if(v > top) top = v; + if(v < bottom) bottom = v; + } + } + } + + float eval(float time, int channel) + { + if(channel >= channels) + return 0; + if(points.len() == 0) + return 0; + if(points.len() == 1) + return points[0].values[channel]; + + time = fmod(time, end_time())*1000.0f; + for(int i = 0; i < points.len() - 1; i++) + { + if(time >= points[i].time && time <= points[i+1].time) + { + float delta = points[i+1].time-points[i].time; + float a = (time-points[i].time)/delta; + + float v0 = fx2f(points[i].values[channel]); + float v1 = fx2f(points[i+1].values[channel]); + + if(points[i].curvetype == CURVETYPE_SMOOTH) + a = -2*a*a*a + 3*a*a; // second hermite basis + else if(points[i].curvetype == CURVETYPE_SLOW) + a = a*a*a; + else if(points[i].curvetype == CURVETYPE_FAST) + { + a = 1-a; + a = 1-a*a*a; + } + else if (points[i].curvetype == CURVETYPE_STEP) + a = 0; + else + { + // linear + } + + return v0 + (v1-v0) * a; + } + } + + return points[points.len()-1].values[channel]; + } + + void add_point(int time, int v0, int v1=0, int v2=0, int v3=0) + { + ENVPOINT p; + p.time = time; + p.values[0] = v0; + p.values[1] = v1; + p.values[2] = v2; + p.values[3] = v3; + p.curvetype = CURVETYPE_LINEAR; + points.add(p); + resort(); + } + + float end_time() + { + if(points.len()) + return points[points.len()-1].time*(1.0f/1000.0f); + return 0; + } +}; + + +class LAYER; +class LAYERGROUP; +class MAP; + +class LAYER +{ +public: + LAYER() + { + type = LAYERTYPE_INVALID; + type_name = "(invalid)"; + visible = true; + readonly = false; + } + + virtual ~LAYER() + { + } + + + virtual void brush_selecting(RECT rect) {} + virtual int brush_grab(LAYERGROUP *brush, RECT rect) { return 0; } + virtual void brush_draw(LAYER *brush, float x, float y) {} + virtual void brush_place(LAYER *brush, float x, float y) {} + virtual void brush_flip_x() {} + virtual void brush_flip_y() {} + + virtual void render() {} + virtual void render_properties(RECT *toolbox) {} + + virtual void get_size(float *w, float *h) { *w = 0; *h = 0;} + + const char *type_name; + int type; + + bool readonly; + bool visible; +}; + +class LAYERGROUP +{ +public: + array<LAYER*> layers; + + int offset_x; + int offset_y; + + int parallax_x; + int parallax_y; + + const char *name; + bool game_group; + bool visible; + + LAYERGROUP(); + ~LAYERGROUP(); + + void convert(RECT *rect); + void render(); + void mapscreen(); + void mapping(float *points); + + bool is_empty() const; + void clear(); + void add_layer(LAYER *l); + + void get_size(float *w, float *h); + + void delete_layer(int index); + int swap_layers(int index0, int index1); +}; + +class IMAGE : public IMAGE_INFO +{ +public: + IMAGE() + { + tex_id = -1; + name[0] = 0; + } + + int tex_id; + char name[128]; +}; + +class MAP +{ +public: + array<LAYERGROUP*> groups; + array<IMAGE*> images; + array<ENVELOPE*> envelopes; + + ENVELOPE *new_envelope(int channels) + { + ENVELOPE *e = new ENVELOPE(channels); + envelopes.add(e); + return e; + } + + LAYERGROUP *new_group() + { + LAYERGROUP *g = new LAYERGROUP; + groups.add(g); + return g; + } + + int swap_groups(int index0, int index1) + { + if(index0 < 0 || index0 >= groups.len()) return index0; + if(index1 < 0 || index1 >= groups.len()) return index0; + if(index0 == index1) return index0; + swap(groups[index0], groups[index1]); + return index1; + } + + void delete_group(int index) + { + if(index < 0 || index >= groups.len()) return; + delete groups[index]; + groups.removebyindex(index); + } +}; + + +struct PROPERTY +{ + const char *name; + int value; + int type; + int min; + int max; +}; + +enum +{ + PROPTYPE_NULL=0, + PROPTYPE_INT_STEP, + PROPTYPE_INT_SCROLL, + PROPTYPE_COLOR, + + PROPS_NONE=0, + PROPS_GROUP, + PROPS_LAYER, + PROPS_QUAD, + PROPS_QUAD_POINT, +}; + +class EDITOR +{ +public: + EDITOR() + { + mode = MODE_LAYERS; + dialog = 0; + tooltip = 0; + + world_offset_x = 0; + world_offset_y = 0; + editor_offset_x = 0.0f; + editor_offset_y = 0.0f; + + world_zoom = 1.0f; + zoom_level = 100; + lock_mouse = false; + mouse_delta_x = 0; + mouse_delta_y = 0; + mouse_delta_wx = 0; + mouse_delta_wy = 0; + + gui_active = true; + proof_borders = false; + + + animate = false; + animate_start = 0; + animate_time = 0; + + props = PROPS_NONE; + + show_envelope_editor = 0; + } + + void make_game_group(LAYERGROUP *group); + void make_game_layer(LAYER *layer); + + int save(const char *filename); + int load(const char *filename); + + QUAD *get_selected_quad(); + LAYER *get_selected_layer_type(int index, int type); + LAYER *get_selected_layer(int index); + LAYERGROUP *get_selected_group(); + + class LAYER_GAME *game_layer; + LAYERGROUP *game_group; + + int do_properties(RECT *toolbox, PROPERTY *props, int *ids, int *new_val); + + int mode; + int dialog; + const char *tooltip; + + float world_offset_x; + float world_offset_y; + float editor_offset_x; + float editor_offset_y; + float world_zoom; + int zoom_level; + bool lock_mouse; + bool gui_active; + bool proof_borders; + float mouse_delta_x; + float mouse_delta_y; + float mouse_delta_wx; + float mouse_delta_wy; + + bool animate; + int64 animate_start; + float animate_time; + + int props; + + int show_envelope_editor; + + MAP map; +}; + +extern EDITOR editor; + +typedef struct +{ + int x, y; + int w, h; +} RECTi; + +class LAYER_TILES : public LAYER +{ +public: + LAYER_TILES(int w, int h); + ~LAYER_TILES(); + + void resize(int new_w, int new_h); + + void make_palette(); + virtual void render(); + + int convert_x(float x) const; + int convert_y(float y) const; + void convert(RECT rect, RECTi *out); + void snap(RECT *rect); + void clamp(RECTi *rect); + + virtual void brush_selecting(RECT rect); + virtual int brush_grab(LAYERGROUP *brush, RECT rect); + virtual void brush_draw(LAYER *brush, float wx, float wy); + virtual void brush_flip_x(); + virtual void brush_flip_y(); + + virtual void render_properties(RECT *toolbox); + + void get_size(float *w, float *h) { *w = width*32.0f; *h = height*32.0f; } + + int tex_id; + int game; + int image; + int width; + int height; + TILE *tiles; +}; + +class LAYER_QUADS : public LAYER +{ +public: + LAYER_QUADS(); + ~LAYER_QUADS(); + + virtual void render(); + QUAD *new_quad(); + + virtual void brush_selecting(RECT rect); + virtual int brush_grab(LAYERGROUP *brush, RECT rect); + virtual void brush_place(LAYER *brush, float wx, float wy); + virtual void brush_flip_x(); + virtual void brush_flip_y(); + + virtual void render_properties(RECT *toolbox); + + void get_size(float *w, float *h); + + int image; + array<QUAD> quads; +}; + + +class LAYER_GAME : public LAYER_TILES +{ +public: + LAYER_GAME(int w, int h); + ~LAYER_GAME(); + + virtual void render_properties(RECT *toolbox); +}; + + +inline void calc_screen_params(float amount, float wmax, float hmax, float aspect, float *w, float *h) +{ + float f = sqrt(amount) / sqrt(aspect); + *w = f*aspect; + *h = f; + + // limit the view + if(*w > wmax) + { + *w = wmax; + *h = *w/aspect; + } + + if(*h > hmax) + { + *h = hmax; + *w = *h*aspect; + } +} + +inline void mapscreen_to_world(float center_x, float center_y, float parallax_x, float parallax_y, + float offset_x, float offset_y, float aspect, float zoom, float *points) +{ + float width, height; + calc_screen_params(1300*1000, 1500, 1050, aspect, &width, &height); + center_x *= parallax_x; + center_y *= parallax_y; + width *= zoom; + height *= zoom; + points[0] = offset_x+center_x-width/2; + points[1] = offset_y+center_y-height/2; + points[2] = offset_x+center_x+width/2; + points[3] = offset_y+center_y+height/2; +} |