void MENUS::ui_draw_grid_header(const void *id, const char *text, int checked, const RECT *r, const void *extra) { if(checked) ui_draw_rect(r, vec4(1,1,1,0.5f), CORNER_T, 5.0f); RECT t; ui_vsplit_l(r, 5.0f, 0, &t); ui_do_label(&t, text, r->h*fontmod_height, -1); }
float MENUS::ui_do_scrollbar_h(const void *id, const RECT *rect, float current) { RECT handle; static float offset_x; ui_vsplit_l(rect, 33, &handle, 0); handle.x += (rect->w-handle.w)*current; /* logic */ float ret = current; int inside = ui_mouse_inside(&handle); if(ui_active_item() == id) { if(!ui_mouse_button(0)) ui_set_active_item(0); float min = rect->x; float max = rect->w-handle.w; float cur = ui_mouse_x()-offset_x; ret = (cur-min)/max; if(ret < 0.0f) ret = 0.0f; if(ret > 1.0f) ret = 1.0f; } else if(ui_hot_item() == id) { if(ui_mouse_button(0)) { ui_set_active_item(id); offset_x = ui_mouse_x()-handle.x; } } if(inside) ui_set_hot_item(id); // render RECT rail; 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; ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_T, 2.5f); slider.y = rail.y+rail.h; ui_draw_rect(&slider, vec4(1,1,1,0.25f), CORNER_B, 2.5f); slider = handle; ui_margin(&slider, 5.0f, &slider); ui_draw_rect(&slider, vec4(1,1,1,0.25f)*button_color_mul(id), CORNER_ALL, 2.5f); return ret; }
void MENUS::ui_do_listbox_start(void *id, const RECT *rect, float row_height, const char *title, int num_items, int selected_index) { RECT scroll, row; RECT view = *rect; RECT header, footer; // draw header ui_hsplit_t(&view, listheader_height, &header, &view); ui_draw_rect(&header, vec4(1,1,1,0.25f), CORNER_T, 5.0f); ui_do_label(&header, title, header.h*fontmod_height, 0); // draw footers ui_hsplit_b(&view, listheader_height, &view, &footer); ui_draw_rect(&footer, vec4(1,1,1,0.25f), CORNER_B, 5.0f); ui_vsplit_l(&footer, 10.0f, 0, &footer); // background ui_draw_rect(&view, vec4(0,0,0,0.15f), 0, 0); // prepare the scroll ui_vsplit_r(&view, 15, &view, &scroll); // setup the variables listbox_originalview = view; listbox_selected_index = selected_index; listbox_new_selected = selected_index; listbox_itemindex = 0; listbox_rowheight = row_height; //int num_servers = client_serverbrowse_sorted_num(); // do the scrollbar ui_hsplit_t(&view, listbox_rowheight, &row, 0); int num = (int)(listbox_originalview.h/row.h); static float scrollvalue = 0; ui_hmargin(&scroll, 5.0f, &scroll); scrollvalue = ui_do_scrollbar_v(id, &scroll, scrollvalue); int start = (int)(num*scrollvalue); if(start < 0) start = 0; // the list listbox_view = listbox_originalview; ui_vmargin(&listbox_view, 5.0f, &listbox_view); ui_clip_enable(&listbox_view); listbox_view.y -= scrollvalue*num*row.h; }
void MENUS::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; ui_vsplit_l(&t, 5.0f, 0, &t); ui_margin(&c, 2.0f, &c); ui_draw_rect(&c, vec4(1,1,1,0.25f)*button_color_mul(id), CORNER_ALL, 3.0f); c.y += 2; ui_do_label(&c, boxtext, r->h*fontmod_height*0.6f, 0); ui_do_label(&t, text, r->h*fontmod_height*0.8f, -1); }
int MENUS::render() { RECT screen = *ui_screen(); gfx_mapscreen(screen.x, screen.y, screen.w, screen.h); static bool first = true; if(first) { if(config.ui_page == PAGE_INTERNET) client_serverbrowse_refresh(0); else if(config.ui_page == PAGE_LAN) client_serverbrowse_refresh(1); first = false; } if(client_state() == CLIENTSTATE_ONLINE) { color_tabbar_inactive = color_tabbar_inactive_ingame; color_tabbar_active = color_tabbar_active_ingame; } else { render_background(); color_tabbar_inactive = color_tabbar_inactive_outgame; color_tabbar_active = color_tabbar_active_outgame; } RECT tab_bar; RECT main_view; // some margin around the screen ui_margin(&screen, 10.0f, &screen); if(popup == POPUP_NONE) { // do tab bar ui_hsplit_t(&screen, 24.0f, &tab_bar, &main_view); ui_vmargin(&tab_bar, 20.0f, &tab_bar); render_menubar(tab_bar); // news is not implemented yet if(config.ui_page <= PAGE_NEWS || config.ui_page > PAGE_SETTINGS || (client_state() == CLIENTSTATE_OFFLINE && config.ui_page >= PAGE_GAME && config.ui_page <= PAGE_CALLVOTE)) { client_serverbrowse_refresh(BROWSETYPE_INTERNET); config.ui_page = PAGE_INTERNET; } // render current page if(client_state() != CLIENTSTATE_OFFLINE) { if(game_page == PAGE_GAME) render_game(main_view); else if(game_page == PAGE_SERVER_INFO) render_serverinfo(main_view); else if(game_page == PAGE_CALLVOTE) render_servercontrol(main_view); else if(game_page == PAGE_SETTINGS) render_settings(main_view); } else if(config.ui_page == PAGE_NEWS) render_news(main_view); else if(config.ui_page == PAGE_INTERNET) render_serverbrowser(main_view); else if(config.ui_page == PAGE_LAN) render_serverbrowser(main_view); else if(config.ui_page == PAGE_DEMOS) render_demolist(main_view); else if(config.ui_page == PAGE_FAVORITES) render_serverbrowser(main_view); else if(config.ui_page == PAGE_SETTINGS) render_settings(main_view); // else if(config.ui_page == PAGE_TEE-NG) // renger_settings(main_teeng); } else { // make sure that other windows doesn't do anything funnay! //ui_set_hot_item(0); //ui_set_active_item(0); char buf[128]; const char *title = ""; const char *extra_text = ""; const char *button_text = ""; int extra_align = 0; if(popup == POPUP_MESSAGE) { title = message_topic; extra_text = message_body; button_text = message_button; } else if(popup == POPUP_CONNECTING) { title = localize("Connecting to"); extra_text = config.ui_server_address; // TODO: query the client about the address button_text = localize("Abort"); if(client_mapdownload_totalsize() > 0) { title = localize("Downloading map"); str_format(buf, sizeof(buf), "%d/%d KiB", client_mapdownload_amount()/1024, client_mapdownload_totalsize()/1024); extra_text = buf; } } else if(popup == POPUP_DISCONNECTED) { title = localize("Disconnected"); extra_text = client_error_string(); button_text = localize("Ok"); extra_align = -1; } else if(popup == POPUP_PURE) { title = localize("Disconnected"); extra_text = localize("The server is running a non-standard tuning on a pure game type."); button_text = localize("Ok"); extra_align = -1; } else if(popup == POPUP_PASSWORD) { title = localize("Password Incorrect"); extra_text = client_error_string(); button_text = localize("Try again"); } else if(popup == POPUP_QUIT) { title = localize("Quit"); extra_text = localize("Are you sure that you want to quit?"); } else if(popup == POPUP_FIRST_LAUNCH) { title = localize("Welcome to Teeworlds"); extra_text = localize("As this is the first time you launch the game, please enter your nick name below. It's recommended that you check the settings to adjust them to your liking before joining a server."); button_text = localize("Ok"); extra_align = -1; } RECT box, part; box = screen; ui_vmargin(&box, 150.0f, &box); ui_hmargin(&box, 150.0f, &box); // render the box ui_draw_rect(&box, vec4(0,0,0,0.5f), CORNER_ALL, 15.0f); 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); if(extra_align == -1) ui_do_label(&part, extra_text, 20.f, -1, (int)part.w); else ui_do_label(&part, extra_text, 20.f, 0, -1); if(popup == POPUP_QUIT) { RECT yes, no; ui_hsplit_b(&box, 20.f, &box, &part); ui_hsplit_b(&box, 24.f, &box, &part); ui_vmargin(&part, 80.0f, &part); ui_vsplit_mid(&part, &no, &yes); ui_vmargin(&yes, 20.0f, &yes); ui_vmargin(&no, 20.0f, &no); static int button_abort = 0; if(ui_do_button(&button_abort, localize("No"), 0, &no, ui_draw_menu_button, 0) || escape_pressed) popup = POPUP_NONE; static int button_tryagain = 0; if(ui_do_button(&button_tryagain, localize("Yes"), 0, &yes, ui_draw_menu_button, 0) || enter_pressed) client_quit(); } else if(popup == POPUP_PASSWORD) { RECT label, textbox, tryagain, abort; ui_hsplit_b(&box, 20.f, &box, &part); ui_hsplit_b(&box, 24.f, &box, &part); ui_vmargin(&part, 80.0f, &part); ui_vsplit_mid(&part, &abort, &tryagain); ui_vmargin(&tryagain, 20.0f, &tryagain); ui_vmargin(&abort, 20.0f, &abort); static int button_abort = 0; if(ui_do_button(&button_abort, localize("Abort"), 0, &abort, ui_draw_menu_button, 0) || escape_pressed) { if(config.cl_autoconnect) config.cl_autoconnect == 0; else popup = POPUP_NONE; } static int button_tryagain = 0; if(ui_do_button(&button_tryagain, localize("Try again"), 0, &tryagain, ui_draw_menu_button, 0) || enter_pressed) { client_connect(config.ui_server_address); } ui_hsplit_b(&box, 60.f, &box, &part); ui_hsplit_b(&box, 24.f, &box, &part); 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, localize("Password"), 20, -1); ui_do_edit_box(&config.password, &textbox, config.password, sizeof(config.password), 14.0f, true); } else if(popup == POPUP_FIRST_LAUNCH) { RECT label, textbox; 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(ui_do_button(&enter_button, localize("Enter"), 0, &part, ui_draw_menu_button, 0) || enter_pressed) popup = POPUP_NONE; ui_hsplit_b(&box, 40.f, &box, &part); ui_hsplit_b(&box, 24.f, &box, &part); 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, localize("Nickname"), 20, -1); ui_do_edit_box(&config.player_name, &textbox, config.player_name, sizeof(config.player_name), 14.0f); } else { 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(ui_do_button(&button, button_text, 0, &part, ui_draw_menu_button, 0) || escape_pressed || enter_pressed) { if(popup == POPUP_CONNECTING) client_disconnect(); popup = POPUP_NONE; } } } return 0; }
int MENUS::render_menubar(RECT r) { RECT box = r; RECT button; int active_page = config.ui_page; int new_page = -1; if(client_state() != CLIENTSTATE_OFFLINE) active_page = game_page; if(client_state() == CLIENTSTATE_OFFLINE) { /* offline menus */ if(0) // this is not done yet { ui_vsplit_l(&box, 90.0f, &button, &box); static int news_button=0; if (ui_do_button(&news_button, localize("News"), active_page==PAGE_NEWS, &button, ui_draw_menu_tab_button, 0)) new_page = PAGE_NEWS; ui_vsplit_l(&box, 30.0f, 0, &box); } ui_vsplit_l(&box, 100.0f, &button, &box); static int internet_button=0; int corners = CORNER_TL; if (ui_do_button(&internet_button, localize("Internet"), active_page==PAGE_INTERNET, &button, ui_draw_menu_tab_button, &corners)) { client_serverbrowse_refresh(BROWSETYPE_INTERNET); new_page = PAGE_INTERNET; } //ui_vsplit_l(&box, 4.0f, 0, &box); ui_vsplit_l(&box, 80.0f, &button, &box); static int lan_button=0; corners = 0; if (ui_do_button(&lan_button, localize("LAN"), active_page==PAGE_LAN, &button, ui_draw_menu_tab_button, &corners)) { client_serverbrowse_refresh(BROWSETYPE_LAN); new_page = PAGE_LAN; } //ui_vsplit_l(&box, 4.0f, 0, &box); ui_vsplit_l(&box, 110.0f, &button, &box); static int favorites_button=0; corners = CORNER_TR; if (ui_do_button(&favorites_button, localize("Favorites"), active_page==PAGE_FAVORITES, &button, ui_draw_menu_tab_button, &corners)) { client_serverbrowse_refresh(BROWSETYPE_FAVORITES); new_page = PAGE_FAVORITES; } ui_vsplit_l(&box, 4.0f*5, 0, &box); ui_vsplit_l(&box, 100.0f, &button, &box); static int demos_button=0; if (ui_do_button(&demos_button, localize("Demos"), active_page==PAGE_DEMOS, &button, ui_draw_menu_tab_button, 0)) { demolist_populate(); new_page = PAGE_DEMOS; } } else { /* online menus */ ui_vsplit_l(&box, 90.0f, &button, &box); static int game_button=0; if (ui_do_button(&game_button, localize("Game"), active_page==PAGE_GAME, &button, ui_draw_menu_tab_button, 0)) new_page = PAGE_GAME; ui_vsplit_l(&box, 4.0f, 0, &box); ui_vsplit_l(&box, 140.0f, &button, &box); static int server_info_button=0; if (ui_do_button(&server_info_button, localize("Server info"), active_page==PAGE_SERVER_INFO, &button, ui_draw_menu_tab_button, 0)) new_page = PAGE_SERVER_INFO; ui_vsplit_l(&box, 4.0f, 0, &box); ui_vsplit_l(&box, 140.0f, &button, &box); static int callvote_button=0; if (ui_do_button(&callvote_button, localize("Call vote"), active_page==PAGE_CALLVOTE, &button, ui_draw_menu_tab_button, 0)) new_page = PAGE_CALLVOTE; ui_vsplit_l(&box, 30.0f, 0, &box); } /* ui_vsplit_r(&box, 110.0f, &box, &button); static int system_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; ui_vsplit_r(&box, 30.0f, &box, 0); */ ui_vsplit_r(&box, 90.0f, &box, &button); static int quit_button=0; if (ui_do_button(&quit_button, localize("Quit"), 0, &button, ui_draw_menu_tab_button, 0)) popup = POPUP_QUIT; ui_vsplit_r(&box, 10.0f, &box, &button); ui_vsplit_r(&box, 130.0f, &box, &button); static int settings_button=0; if (ui_do_button(&settings_button, localize("Settings"), active_page==PAGE_SETTINGS, &button, ui_draw_menu_tab_button, 0)) new_page = PAGE_SETTINGS; if(new_page != -1) { if(client_state() == CLIENTSTATE_OFFLINE) config.ui_page = new_page; else game_page = new_page; } return 0; }
void MENUS::render_settings_player(RECT main_view) { RECT button; RECT skinselection; ui_vsplit_l(&main_view, 300.0f, &main_view, &skinselection); ui_hsplit_t(&main_view, 20.0f, &button, &main_view); // render settings { 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); if(ui_do_edit_box(config.player_name, &button, config.player_name, sizeof(config.player_name), 14.0f)) need_sendinfo = true; static int dynamic_camera_button = 0; ui_hsplit_t(&main_view, 20.0f, &button, &main_view); if(ui_do_button(&dynamic_camera_button, "Dynamic Camera", config.cl_mouse_deadzone != 0, &button, ui_draw_checkbox, 0)) { if(config.cl_mouse_deadzone) { config.cl_mouse_followfactor = 0; config.cl_mouse_max_distance = 400; config.cl_mouse_deadzone = 0; } else { config.cl_mouse_followfactor = 60; config.cl_mouse_max_distance = 1000; config.cl_mouse_deadzone = 300; } } 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; ui_hsplit_t(&main_view, 20.0f, &button, &main_view); if(ui_do_button(&config.cl_scoreboard_client_id, "Show Client ID in scoreboard", config.cl_scoreboard_client_id, &button, ui_draw_checkbox, 0)) config.cl_scoreboard_client_id ^= 1; 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) { 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; ui_hsplit_t(&main_view, 20.0f, &button, &main_view); ui_vsplit_l(&button, 15.0f, 0, &button); if(ui_do_button(&config.cl_nameplate_client_id, "Client ID", config.cl_nameplate_client_id, &button, ui_draw_checkbox, 0)) config.cl_nameplate_client_id ^= 1; } ui_hsplit_t(&main_view, 20.0f, &button, &main_view); 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; need_sendinfo = true; } if(config.player_use_custom_color) { int *colors[2]; colors[0] = &config.player_color_body; colors[1] = &config.player_color_feet; const char *parts[] = {"Body", "Feet"}; const char *labels[] = {"Hue", "Sat.", "Lht."}; static int color_slider[2][3] = {{0}}; //static float v[2][3] = {{0, 0.5f, 0.25f}, {0, 0.5f, 0.25f}}; for(int i = 0; i < 2; i++) { RECT text; 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; 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 = ui_do_scrollbar_h(&color_slider[i][s], &button, k); color <<= 8; color += clamp((int)(k*255), 0, 255); ui_do_label(&text, labels[s], 15.0f, -1); } if(*colors[i] != color) need_sendinfo = true; *colors[i] = color; ui_hsplit_t(&main_view, 5.0f, 0, &main_view); } } }
void MENUS::render_demoplayer(RECT main_view) { const DEMOPLAYBACK_INFO *info = client_demoplayer_getinfo(); const float seekbar_height = 15.0f; const float buttonbar_height = 20.0f; const float margins = 5.0f; float total_height; if(menu_active) { total_height = seekbar_height+buttonbar_height+margins*3; /* else total_height = seekbar_height+margins*2; */ ui_hsplit_b(&main_view, total_height, 0, &main_view); ui_vsplit_l(&main_view, 250.0f, 0, &main_view); ui_vsplit_r(&main_view, 250.0f, &main_view, 0); ui_draw_rect(&main_view, color_tabbar_active, CORNER_T, 10.0f); ui_margin(&main_view, 5.0f, &main_view); } RECT seekbar, buttonbar; if(menu_active) { ui_hsplit_t(&main_view, seekbar_height, &seekbar, &buttonbar); ui_hsplit_t(&buttonbar, margins, 0, &buttonbar); } /* else seekbar = main_view; */ // do seekbar if(menu_active) { static int seekbar_id = 0; void *id = &seekbar_id; char buffer[128]; ui_draw_rect(&seekbar, vec4(0,0,0,0.5f), CORNER_ALL, 5.0f); int current_tick = info->current_tick - info->first_tick; int total_ticks = info->last_tick - info->first_tick; float amount = current_tick/(float)total_ticks; RECT filledbar = seekbar; filledbar.w = 10.0f + (filledbar.w-10.0f)*amount; ui_draw_rect(&filledbar, vec4(1,1,1,0.5f), CORNER_ALL, 5.0f); str_format(buffer, sizeof(buffer), "%d:%02d / %d:%02d", current_tick/SERVER_TICK_SPEED/60, (current_tick/SERVER_TICK_SPEED)%60, total_ticks/SERVER_TICK_SPEED/60, (total_ticks/SERVER_TICK_SPEED)%60); ui_do_label(&seekbar, buffer, seekbar.h*0.70f, 0); // do the logic int inside = ui_mouse_inside(&seekbar); if(ui_active_item() == id) { if(!ui_mouse_button(0)) ui_set_active_item(0); else { float amount = (ui_mouse_x()-seekbar.x)/(float)seekbar.w; if(amount > 0 && amount < 1.0f) { gameclient.on_reset(); gameclient.suppress_events = true; client_demoplayer_setpos(amount); gameclient.suppress_events = false; } } } else if(ui_hot_item() == id) { if(ui_mouse_button(0)) ui_set_active_item(id); } if(inside) ui_set_hot_item(id); } if(menu_active) { // do buttons RECT button; // pause button ui_vsplit_l(&buttonbar, buttonbar_height, &button, &buttonbar); static int pause_button = 0; if(ui_do_button(&pause_button, "| |", info->paused, &button, ui_draw_demoplayer_button, 0)) client_demoplayer_setpause(!info->paused); // play button ui_vsplit_l(&buttonbar, margins, 0, &buttonbar); ui_vsplit_l(&buttonbar, buttonbar_height, &button, &buttonbar); static int play_button = 0; if(ui_do_button(&play_button, ">", !info->paused, &button, ui_draw_demoplayer_button, 0)) { client_demoplayer_setpause(0); client_demoplayer_setspeed(1.0f); } // slowdown ui_vsplit_l(&buttonbar, margins, 0, &buttonbar); ui_vsplit_l(&buttonbar, buttonbar_height, &button, &buttonbar); static int slowdown_button = 0; if(ui_do_button(&slowdown_button, "<<", 0, &button, ui_draw_demoplayer_button, 0)) { if(info->speed > 4.0f) client_demoplayer_setspeed(4.0f); else if(info->speed > 2.0f) client_demoplayer_setspeed(2.0f); else if(info->speed > 1.0f) client_demoplayer_setspeed(1.0f); else if(info->speed > 0.5f) client_demoplayer_setspeed(0.5f); else client_demoplayer_setspeed(0.05f); } // fastforward ui_vsplit_l(&buttonbar, margins, 0, &buttonbar); ui_vsplit_l(&buttonbar, buttonbar_height, &button, &buttonbar); static int fastforward_button = 0; if(ui_do_button(&fastforward_button, ">>", 0, &button, ui_draw_demoplayer_button, 0)) { if(info->speed < 0.5f) client_demoplayer_setspeed(0.5f); else if(info->speed < 1.0f) client_demoplayer_setspeed(1.0f); else if(info->speed < 2.0f) client_demoplayer_setspeed(2.0f); else if(info->speed < 4.0f) client_demoplayer_setspeed(4.0f); else client_demoplayer_setspeed(8.0f); } // speed meter ui_vsplit_l(&buttonbar, margins*3, 0, &buttonbar); char buffer[64]; if(info->speed >= 1.0f) str_format(buffer, sizeof(buffer), "x%.0f", info->speed); else str_format(buffer, sizeof(buffer), "x%.1f", info->speed); ui_do_label(&buttonbar, buffer, button.h*0.7f, -1); // exit button ui_vsplit_r(&buttonbar, buttonbar_height*3, &buttonbar, &button); static int exit_button = 0; if(ui_do_button(&exit_button, "Exit", 0, &button, ui_draw_demoplayer_button, 0)) client_disconnect(); } }