diff --git a/code/hud/hudconfig.cpp b/code/hud/hudconfig.cpp index e1bfb009ab..c079a903c9 100644 --- a/code/hud/hudconfig.cpp +++ b/code/hud/hudconfig.cpp @@ -865,6 +865,25 @@ void hud_config_set_mouse_coords(int gauge_config, int x1, int x2, int y1, int y HC_gauge_mouse_coords[gauge_config] = {x1, x2, y1, y2}; } +// ETS gauge can render as one unified gauge or as three separate gauges using separate drawing functions +// So this function provides a way to min/max the coords to make sure no matter what method is used, the +// mouse box inclues all the relevant areas +void hud_config_set_mouse_coords_ets(int gauge_config, int x1, int x2, int y1, int y2) +{ + HC_gauge_mouse_coords[gauge_config].x1 = std::min(HC_gauge_mouse_coords[gauge_config].x1, x1); + HC_gauge_mouse_coords[gauge_config].x2 = std::max(HC_gauge_mouse_coords[gauge_config].x2, x2); + HC_gauge_mouse_coords[gauge_config].y1 = std::min(HC_gauge_mouse_coords[gauge_config].y1, y1); + HC_gauge_mouse_coords[gauge_config].y2 = std::max(HC_gauge_mouse_coords[gauge_config].y2, y2); + + // temporary stuff to show boxes + color clr = gr_screen.current_color; + color thisColor; + gr_init_alphacolor(&thisColor, 255, 255, 255, 80); + gr_set_color_fast(&thisColor); + // hud_config_draw_box(x1, x2, y1, y2); + gr_set_color_fast(&clr); +} + std::pair hud_config_convert_coords(int x, int y, float scale) { int outX = HC_gauge_coordinates[0] + static_cast(x * scale); diff --git a/code/hud/hudconfig.h b/code/hud/hudconfig.h index 4b2519a772..ce843a80f1 100644 --- a/code/hud/hudconfig.h +++ b/code/hud/hudconfig.h @@ -279,5 +279,11 @@ std::tuple hud_config_convert_coord_sys(float x, float y, i */ void hud_config_set_mouse_coords(int gauge_config, int x1, int x2, int y1, int y2); +/*! + * @brief save gauge coords during rendering time so hud config can check if the mouse is hovering over the gauge + * @brief this one is specific to the ETS gauge's individual rendering method + */ +void hud_config_set_mouse_coords_ets(int gauge_config, int x1, int x2, int y1, int y2); + #endif diff --git a/code/hud/hudescort.cpp b/code/hud/hudescort.cpp index 2277174c99..963c28d0ff 100644 --- a/code/hud/hudescort.cpp +++ b/code/hud/hudescort.cpp @@ -234,174 +234,240 @@ int HudGaugeEscort::setGaugeColorEscort(int index, int team) return is_flashing; } -void HudGaugeEscort::render(float /*frametime*/, bool /*config*/) +void HudGaugeEscort::render(float /*frametime*/, bool config) { - int i = 0; - if (Escort_gauges[0].first_frame < 0) return; - if ( !Show_escort_view ) { + if (!config && !Show_escort_view ) { return; } - if ( Escort_ships.empty() ) { + if (!config && Escort_ships.empty() ) { return; } + int x = position[0]; + int y = position[1]; + float scale = 1.0; + + if (config) { + std::tie(x, y, scale) = hud_config_convert_coord_sys(position[0], position[1], base_w, base_h); + } + // hud_set_default_color(); - setGaugeColor(); + setGaugeColor(HUD_C_NONE, config); // draw the top of the escort view - renderBitmap(Escort_gauges[0].first_frame, position[0], position[1]); - renderString(position[0] + header_text_offsets[0], position[1] + header_text_offsets[1], header_text); + renderBitmap(Escort_gauges[0].first_frame, x, y, scale, config); + renderString(x + fl2i(header_text_offsets[0] * scale), y + fl2i(header_text_offsets[1] * scale), header_text, scale, config); - int x = position[0] + list_start_offsets[0]; - int y = position[1] + list_start_offsets[1]; + int lx = x + fl2i(list_start_offsets[0] * scale); + int ly = y + fl2i(list_start_offsets[1] * scale); - //This is temporary - int num_escort_ships = std::min(hud_escort_num_ships_on_list(), Max_escort_ships) - 1; - i=0; + //This is temporary. Oh really? + int num_escort_ships = config ? 2 : std::min(hud_escort_num_ships_on_list(), Max_escort_ships) - 1; + if (num_escort_ships > 0) { + for (int i = 0; i < num_escort_ships; i++) { + renderBitmap(Escort_gauges[1].first_frame, lx, ly, scale, config); + renderIcon(lx, ly, i, scale, config); - if(num_escort_ships > 0) - { - for(; i < num_escort_ships; i++) - { - if(i != 0) - { - x += entry_stagger_w; - y += entry_h; - } - renderBitmap(Escort_gauges[1].first_frame, x, y); - - //Now we just show the ships info - renderIcon(x, y, i); + // Apply offset for next entry + lx += fl2i(entry_stagger_w * scale); + ly += fl2i(entry_h * scale); } - - //Increment for last entry - x += entry_stagger_w; - y += entry_h; } - //Show the last escort entry - renderBitmap(Escort_gauges[2].first_frame, x, y + bottom_bg_offset); - renderIcon(x, y, i); + // Show the last escort entry (already positioned correctly) + renderBitmap(Escort_gauges[2].first_frame, lx, ly + fl2i(bottom_bg_offset * scale), scale, config); + renderIcon(lx, ly, num_escort_ships, scale, config); + + // Now that we know the height of the list, we can send the coords to hud config + if (config) { + int bmw, bmh; + bm_get_info(Escort_gauges[2].first_frame, &bmw, &bmh); + hud_config_set_mouse_coords(gauge_config, x, lx + fl2i(bmw * scale), y, ly + fl2i(bmh * scale)); + } } // draw the shield icon and integrity for the escort ship -void HudGaugeEscort::renderIcon(int x, int y, int index) +void HudGaugeEscort::renderIcon(int x, int y, int index, float scale, bool config) { - if(MULTI_DOGFIGHT && index <= 2) + if(!config && MULTI_DOGFIGHT && index <= 2) { renderIconDogfight(x, y, index); return; } - float shields, integrity; - int screen_integrity, offset, objnum = -1; - char buf[255]; - auto eship = get_escort_entry_from_index(index); - if (eship == Escort_ships.end()) { + if (!config && eship == Escort_ships.end()) { return; } - if ( (Game_mode & GM_MULTIPLAYER) && (eship->np_id >= 0) ) { - int np_index = find_player_index(eship->np_id); + int objnum = -1; + if (!config) { + if ((Game_mode & GM_MULTIPLAYER) && (eship->np_id >= 0)) { + int np_index = find_player_index(eship->np_id); - if (np_index >= 0) { - objnum = Net_players[np_index].m_player->objnum; + if (np_index >= 0) { + objnum = Net_players[np_index].m_player->objnum; - // this can occassionally happen in multi when a player still needs to respawn. - if (objnum < 0 || Objects[objnum].type != OBJ_SHIP){ - return; + // this can occassionally happen in multi when a player still needs to respawn. + if (objnum < 0 || Objects[objnum].type != OBJ_SHIP) { + return; + } } - + + } else { + objnum = eship->objnum; } + if (objnum < 0) { + return; + } + } + + object* objp = nullptr; + ship* sp = nullptr; + + if (!config) { + objp = &Objects[objnum]; + sp = &Ships[objp->instance]; + + // determine if its "friendly" or not + // Goober5000 - changed in favor of just passing the team + setGaugeColorEscort(index, sp->team); } else { - objnum = eship->objnum; + // For config we do friendly, friendly disable, and hostile in that order + // But try to find defined IFFs that match, else just use red and green + bool found; + switch (index) { + case 2: + // Try to find hostile + found = false; + for (iff_info& iff : Iff_info) { + if (!stricmp(iff.iff_name, "hostile")) { + gr_set_color_fast(iff_get_color(iff.color_index, false)); + found = true; + break; + } + } + if (!found) { + gr_set_color_fast(&Color_bright_red); + } + break; + default: + // Try to find friendly + found = false; + for (iff_info& iff : Iff_info) { + if (!stricmp(iff.iff_name, "friendly")) { + gr_set_color_fast(iff_get_color(iff.color_index, false)); + found = true; + break; + } + } + if (!found) { + gr_set_color_fast(&Color_bright_green); + } + break; + } } - if (objnum < 0) { - return; - } - - object *objp = &Objects[objnum]; - ship *sp = &Ships[objp->instance]; - - // determine if its "friendly" or not - // Goober5000 - changed in favor of just passing the team - setGaugeColorEscort(index, sp->team); - /* - if(Player_ship != NULL){ - hud_escort_set_gauge_color(index, (sp->team == Player_ship->team) ? 1 : 0); - } else { - hud_escort_set_gauge_color(index, 1); - } - */ - // draw a 'D' if a ship is disabled - if ( (sp->flags[Ship::Ship_Flags::Disabled]) || (ship_subsys_disrupted(sp, SUBSYSTEM_ENGINE)) ) { - renderString( x + ship_status_offsets[0], y + ship_status_offsets[1], EG_NULL, XSTR( "D", 284)); + if ((config && index == 1) || (!config && (( (sp->flags[Ship::Ship_Flags::Disabled]) || (ship_subsys_disrupted(sp, SUBSYSTEM_ENGINE)) )))) { + renderString( x + fl2i(ship_status_offsets[0] * scale), y + fl2i(ship_status_offsets[1] * scale), EG_NULL, XSTR( "D", 284), scale, config); } // print out ship name // original behavior replaced with similar logic to hudtargetbox.cpp, except // if the name is hidden, it's replaced with the class name. - if (((Iff_info[sp->team].flags & IFFF_WING_NAME_HIDDEN) && (sp->wingnum != -1)) || (sp->flags[Ship::Ship_Flags::Hide_ship_name])) - { - // If we're hiding the ship name, we probably shouldn't append the callsign either - hud_stuff_ship_class(buf, sp); - } - else - { - hud_stuff_ship_name(buf, sp); + char buf[255]; + if (!config) { + if (((Iff_info[sp->team].flags & IFFF_WING_NAME_HIDDEN) && (sp->wingnum != -1)) || + (sp->flags[Ship::Ship_Flags::Hide_ship_name])) { + // If we're hiding the ship name, we probably shouldn't append the callsign either + hud_stuff_ship_class(buf, sp); + } else { + hud_stuff_ship_name(buf, sp); - if (!Dont_show_callsigns_in_escort_list) - { - // maybe concatenate the callsign - if (*buf) - { - char callsign[NAME_LENGTH]; + if (!Dont_show_callsigns_in_escort_list) { + // maybe concatenate the callsign + if (*buf) { + char callsign[NAME_LENGTH]; - hud_stuff_ship_callsign(callsign, sp); - if (*callsign) - sprintf(&buf[strlen(buf)], " (%s)", callsign); - } - // maybe substitute the callsign - else - { - hud_stuff_ship_callsign(buf, sp); + hud_stuff_ship_callsign(callsign, sp); + if (*callsign) + sprintf(&buf[strlen(buf)], " (%s)", callsign); + } + // maybe substitute the callsign + else { + hud_stuff_ship_callsign(buf, sp); + } } } + } else { + switch (index) { + case 0: + strcpy(buf, "Friendly Ship"); + break; + case 1: + strcpy(buf, "Friendly Disabled Ship"); + break; + case 2: + strcpy(buf, "Hostile Ship"); + break; + default: + strcpy(buf, "Escort Ship"); + break; + } } - const int w = font::force_fit_string(buf, 255, ship_name_max_width); + const int w = font::force_fit_string(buf, 255, fl2i(ship_name_max_width * scale), scale); if (right_align_names) { - renderString( x + ship_name_offsets[0] + ship_name_max_width - w, y + ship_name_offsets[1], EG_ESCORT1 + index, buf); + renderString( x + fl2i(ship_name_offsets[0] * scale) + fl2i(ship_name_max_width * scale) - w, y + fl2i(ship_name_offsets[1] * scale), EG_ESCORT1 + index, buf, scale, config); } else { - renderString( x + ship_name_offsets[0], y + ship_name_offsets[1], EG_ESCORT1 + index, buf); + renderString( x + fl2i(ship_name_offsets[0] * scale), y + fl2i(ship_name_offsets[1] * scale), EG_ESCORT1 + index, buf, scale, config); } + int screen_integrity; + // show ship integrity - hud_get_target_strength(objp, &shields, &integrity); - screen_integrity = (int)std::lround(integrity * 100); - offset = 0; - if ( screen_integrity < 100 ) { + float integrity = 0.0f; + if (!config) { + float shields; + hud_get_target_strength(objp, &shields, &integrity); + screen_integrity = fl2i(std::lround(integrity * 100)); + } else { + switch (index) { + case 1: + screen_integrity = 25; + break; + case 2: + screen_integrity = 50; + break; + default: + screen_integrity = 100; + break; + } + } + + // set offsets based on integrity + int offset = 0; + if (screen_integrity < 100) { offset = 2; - if ( screen_integrity == 0 ) { - if ( integrity > 0 ) { + if (screen_integrity == 0) { + if (integrity > 0) { screen_integrity = 1; } } } - renderPrintfWithGauge( x+ship_integrity_offsets[0] + offset, y+ship_integrity_offsets[1], EG_NULL, 1.0f, false, "%d", screen_integrity); + + renderPrintfWithGauge( x+fl2i(ship_integrity_offsets[0] * scale) + offset, y+fl2i(ship_integrity_offsets[1] * scale), EG_NULL, scale, config, "%d", screen_integrity); //Let's be nice. - setGaugeColor(); + setGaugeColor(HUD_C_NONE, config); } // multiplayer dogfight diff --git a/code/hud/hudescort.h b/code/hud/hudescort.h index 9172927f18..e1ed729887 100644 --- a/code/hud/hudescort.h +++ b/code/hud/hudescort.h @@ -31,9 +31,9 @@ void hud_escort_ship_hit(const object *objp, int quadrant); void hud_escort_target_next(); void hud_escort_cull_list(); void hud_add_ship_to_escort(int objnum, int supress_feedback); -void hud_remove_ship_from_escort(int objnum); -int hud_escort_num_ships_on_list(); -int hud_escort_return_objnum(int index); +void hud_remove_ship_from_escort(int objnum); +int hud_escort_num_ships_on_list(); +int hud_escort_return_objnum(int index); void hud_escort_add_player(short id); void hud_escort_remove_player(short id); @@ -70,7 +70,7 @@ public: int setGaugeColorEscort(int index, int team); void render(float frametime, bool config = false) override; void pageIn() override; - void renderIcon(int x, int y, int index); + void renderIcon(int x, int y, int index, float scale, bool config); void renderIconDogfight(int x, int y, int index); }; diff --git a/code/hud/hudets.cpp b/code/hud/hudets.cpp index 4ae9b784af..881775fe44 100644 --- a/code/hud/hudets.cpp +++ b/code/hud/hudets.cpp @@ -899,81 +899,87 @@ void HudGaugeEts::pageIn() /** * Draw one ETS bar to screen */ -void HudGaugeEts::blitGauge(int index) +void HudGaugeEts::blitGauge(int index, int ix, int iy, float scale, bool config) { if (Ets_bar.first_frame < 0) { return; } - int y_start, y_end, clip_h, w, h, x, y; - - clip_h = fl2i( (1 - Energy_levels[index]) * ETS_bar_h ); + int clip_h = fl2i( (1 - Energy_levels[index]) * ETS_bar_h ); + int w, h; bm_get_info(Ets_bar.first_frame,&w,&h); + int x, y; if (HUD_shadows) { // These act more as a backing black layer. gr_set_color_fast(&Color_black); // draw the top portion - x = position[0] + Top_offsets[0]; - y = position[1] + Top_offsets[1]; + x = ix + fl2i(Top_offsets[0] * scale); + y = iy + fl2i(Top_offsets[1] * scale); - renderBitmapEx(Ets_bar.first_frame,x,y,w,ETS_bar_h,0,0); + renderBitmapEx(Ets_bar.first_frame,x,y,w,ETS_bar_h,0,0, scale, config); // draw the bottom portion - x = position[0] + Bottom_offsets[0]; - y = position[1] + Bottom_offsets[1]; + x = ix + fl2i(Bottom_offsets[0] * scale); + y = iy + fl2i(Bottom_offsets[1] * scale); - renderBitmapEx(Ets_bar.first_frame, x, y, w, y + ETS_bar_h, 0, 0); - gr_set_color_fast(&gauge_color); + renderBitmapEx(Ets_bar.first_frame, x, y, w, y + ETS_bar_h, 0, 0, scale, config); + + if (!config) { + gr_set_color_fast(&gauge_color); + } else { + setGaugeColor(HUD_C_NONE, config); + } } + int y_start, y_end; if ( index < NUM_ENERGY_LEVELS-1 ) { // some portion of dark needs to be drawn - setGaugeColor(); + setGaugeColor(HUD_C_NONE, config); // draw the top portion - x = position[0] + Top_offsets[0]; - y = position[1] + Top_offsets[1]; + x = ix + fl2i(Top_offsets[0] * scale); + y = iy + fl2i(Top_offsets[1] * scale); - renderBitmapEx(Ets_bar.first_frame,x,y,w,clip_h,0,0); + renderBitmapEx(Ets_bar.first_frame,x,y,w,clip_h,0,0, scale, config); // draw the bottom portion - x = position[0] + Bottom_offsets[0]; - y = position[1] + Bottom_offsets[1]; + x = ix + fl2i(Bottom_offsets[0] * scale); + y = iy + fl2i(Bottom_offsets[1] * scale); - y_start = y + (ETS_bar_h - clip_h); + y_start = y + fl2i((ETS_bar_h - clip_h) * scale); y_end = y + ETS_bar_h; - renderBitmapEx(Ets_bar.first_frame, x, y_start, w, y_end-y_start, 0, ETS_bar_h-clip_h); + renderBitmapEx(Ets_bar.first_frame, x, y_start, w, y_end-y_start, 0, ETS_bar_h-clip_h, scale, config); } if ( index > 0 ) { - if ( maybeFlashSexp() == 1 ) { - setGaugeColor(HUD_C_DIM); + if (!config && maybeFlashSexp() == 1 ) { + setGaugeColor(HUD_C_DIM, config); // hud_set_dim_color(); } else { - setGaugeColor(HUD_C_BRIGHT); + setGaugeColor(HUD_C_BRIGHT, config); // hud_set_bright_color(); } // some portion of recharge needs to be drawn // draw the top portion - x = position[0] + Top_offsets[0]; - y = position[1] + Top_offsets[1]; + x = ix + fl2i(Top_offsets[0] * scale); + y = iy + fl2i(Top_offsets[1] * scale); - y_start = y + clip_h; + y_start = y + fl2i(clip_h * scale); y_end = y + ETS_bar_h; - renderBitmapEx(Ets_bar.first_frame+1, x, y_start, w, y_end-y_start, 0, clip_h); + renderBitmapEx(Ets_bar.first_frame+1, x, y_start, w, y_end-y_start, 0, clip_h, scale, config); // draw the bottom portion - x = position[0] + Bottom_offsets[0]; - y = position[1] + Bottom_offsets[1]; + x = ix + fl2i(Bottom_offsets[0] * scale); + y = iy + fl2i(Bottom_offsets[1] * scale); - renderBitmapEx(Ets_bar.first_frame+2, x,y,w,ETS_bar_h-clip_h,0,0); + renderBitmapEx(Ets_bar.first_frame+2, x,y,w,ETS_bar_h-clip_h,0,0, scale, config); } } @@ -989,61 +995,112 @@ HudGaugeEts(HUD_OBJECT_ETS_RETAIL, 0) /** * Render the ETS retail gauge to the screen (weapon+shield+engine) */ -void HudGaugeEtsRetail::render(float /*frametime*/, bool /*config*/) +void HudGaugeEtsRetail::render(float /*frametime*/, bool config) { - int i; - int initial_position; - - ship* ship_p = &Ships[Player_obj->instance]; + ship* ship_p = nullptr; + if (!config) { + ship_p = &Ships[Player_obj->instance]; + } if ( Ets_bar.first_frame < 0 ) { return; } + int x = position[0]; + int y = position[1]; + float scale = 1.0; + + if (config) { + std::tie(x, y, scale) = hud_config_convert_coord_sys(position[0], position[1], base_w, base_h); + } + // if at least two gauges are not shown, don't show any - i = 0; - if (!ship_has_energy_weapons(ship_p)) i++; - if (Player_obj->flags[Object::Object_Flags::No_shields]) i++; - if (!ship_has_engine_power(ship_p)) i++; - if (i >= 2) return; + if (!config) { + int i = 0; + if (!ship_has_energy_weapons(ship_p)) + i++; + if (Player_obj->flags[Object::Object_Flags::No_shields]) + i++; + if (!ship_has_engine_power(ship_p)) + i++; + if (i >= 2) + return; + } - setGaugeColor(); + setGaugeColor(HUD_C_NONE, config); // draw the letters for the gauges first, before any clipping occurs // skip letter for any missing gauges (max one, see check above) - initial_position = 0; - if (ship_has_energy_weapons(ship_p)) { + int initial_position = 0; + if (config || ship_has_energy_weapons(ship_p)) { Letter = Letters[0]; - position[0] = Gauge_positions[initial_position++]; - renderPrintf(position[0] + Letter_offsets[0], position[1] + Letter_offsets[1], 1.0f, false, NOX("%c"), Letter); + int rx = Gauge_positions[initial_position++] + Letter_offsets[0]; + int ry = position[1] + Letter_offsets[1]; // Explicitely use unconverted y here + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + renderPrintf(rx, ry, scale, config, NOX("%c"), Letter); } - if (!(Player_obj->flags[Object::Object_Flags::No_shields])) { + if (config || !(Player_obj->flags[Object::Object_Flags::No_shields])) { Letter = Letters[1]; - position[0] = Gauge_positions[initial_position++]; - renderPrintf(position[0] + Letter_offsets[0], position[1] + Letter_offsets[1], 1.0f, false, NOX("%c"), Letter); + int rx = Gauge_positions[initial_position++] + Letter_offsets[0]; + int ry = position[1] + Letter_offsets[1]; // Explicitely use unconverted y here + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + renderPrintf(rx, ry, scale, config, NOX("%c"), Letter); } - if (ship_has_engine_power(ship_p)) { + if (config || ship_has_engine_power(ship_p)) { Letter = Letters[2]; - position[0] = Gauge_positions[initial_position++]; - renderPrintf(position[0] + Letter_offsets[0], position[1] + Letter_offsets[1], 1.0f, false, NOX("%c"), Letter); + int rx = Gauge_positions[initial_position++] + Letter_offsets[0]; + int ry = position[1] + Letter_offsets[1]; // Explicitely use unconverted y here + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + renderPrintf(rx, ry, scale, config, NOX("%c"), Letter); } // draw gauges, skipping any gauge that is missing initial_position = 0; - if (ship_has_energy_weapons(ship_p)) { + if (config || ship_has_energy_weapons(ship_p)) { Letter = Letters[0]; - position[0] = Gauge_positions[initial_position++]; - blitGauge(ship_p->weapon_recharge_index); + int level = config ? 4 : ship_p->weapon_recharge_index; + int rx = Gauge_positions[initial_position++]; + int ry = position[1]; + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + blitGauge(level, rx, ry, scale, config); } - if (!(Player_obj->flags[Object::Object_Flags::No_shields])) { + if (config || !(Player_obj->flags[Object::Object_Flags::No_shields])) { Letter = Letters[1]; - position[0] = Gauge_positions[initial_position++]; - blitGauge(ship_p->shield_recharge_index); + int level = config ? 4 : ship_p->shield_recharge_index; + int rx = Gauge_positions[initial_position++]; + int ry = position[1]; + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + blitGauge(level, rx, ry, scale, config); } - if (ship_has_engine_power(ship_p)) { + if (config || ship_has_engine_power(ship_p)) { Letter = Letters[2]; - position[0] = Gauge_positions[initial_position++]; - blitGauge(ship_p->engine_recharge_index); + int level = config ? 4 : ship_p->engine_recharge_index; + int rx = Gauge_positions[initial_position++]; + int ry = position[1]; + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + blitGauge(level, rx, ry, scale, config); + } + + if (config) { + int bmw, bmh; + bm_get_info(Ets_bar.first_frame, &bmw, &bmh); + + auto coords1 = hud_config_convert_coords(Gauge_positions[0], position[1], scale); + auto coords2 = hud_config_convert_coords(Gauge_positions[initial_position - 1] + bmw, position[1] + (bmh * 2) + 10, scale); + + hud_config_set_mouse_coords(gauge_config, coords1.first, coords2.first, coords1.second, coords2.second); } } @@ -1073,36 +1130,69 @@ HudGaugeEts(HUD_OBJECT_ETS_WEAPONS, (int)WEAPONS) { } -void HudGaugeEtsWeapons::render(float /*frametime*/, bool /*config*/) +void HudGaugeEtsWeapons::render(float /*frametime*/, bool config) { - int i; - - ship* ship_p = &Ships[Player_obj->instance]; + ship* ship_p = nullptr; + if (!config) { + ship_p = &Ships[Player_obj->instance]; + } if ( Ets_bar.first_frame < 0 ) { return; } - // if at least two gauges are not shown, don't show any - i = 0; - if (!ship_has_energy_weapons(ship_p)) i++; - if (Player_obj->flags[Object::Object_Flags::No_shields]) i++; - if (!ship_has_engine_power(ship_p)) i++; - if (i >= 2) return; + int x = position[0]; + int y = position[1]; + float scale = 1.0; - // no weapon energy, no weapon gauge - if (!ship_has_energy_weapons(ship_p)) - { - return; + if (config) { + std::tie(x, y, scale) = hud_config_convert_coord_sys(position[0], position[1], base_w, base_h); } - setGaugeColor(); + + // if at least two gauges are not shown, don't show any + if (!config) { + int i = 0; + if (!ship_has_energy_weapons(ship_p)) + i++; + if (Player_obj->flags[Object::Object_Flags::No_shields]) + i++; + if (!ship_has_engine_power(ship_p)) + i++; + if (i >= 2) + return; + + // no weapon energy, no weapon gauge + if (!ship_has_energy_weapons(ship_p)) { + return; + } + } + + setGaugeColor(HUD_C_NONE, config); // draw the letters for the gauge first, before any clipping occurs - renderPrintf(position[0] + Letter_offsets[0], position[1] + Letter_offsets[1], 1.0f, false, NOX("%c"), Letter); + int rx = position[0] + Letter_offsets[0]; + int ry = position[1] + Letter_offsets[1]; + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + renderPrintf(rx, ry, scale, config, NOX("%c"), Letter); // draw the gauges for the weapon system - blitGauge(ship_p->weapon_recharge_index); + int level = config ? 4 : ship_p->weapon_recharge_index; + rx = position[0]; + ry = position[1]; + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + blitGauge(level, rx, ry, scale, config); + + if (config) { + int bmw, bmh; + bm_get_info(Ets_bar.first_frame, &bmw, &bmh); + + hud_config_set_mouse_coords_ets(gauge_config, rx, rx + bmw, ry, ry + (bmh * 2) + 10); + } } HudGaugeEtsShields::HudGaugeEtsShields(): @@ -1110,35 +1200,69 @@ HudGaugeEts(HUD_OBJECT_ETS_SHIELDS, (int)SHIELDS) { } -void HudGaugeEtsShields::render(float /*frametime*/, bool /*config*/) +void HudGaugeEtsShields::render(float /*frametime*/, bool config) { - int i; - - ship* ship_p = &Ships[Player_obj->instance]; + ship* ship_p = nullptr; + if (!config) { + ship_p = &Ships[Player_obj->instance]; + } if ( Ets_bar.first_frame < 0 ) { return; } - // if at least two gauges are not shown, don't show any - i = 0; - if (!ship_has_energy_weapons(ship_p)) i++; - if (Player_obj->flags[Object::Object_Flags::No_shields]) i++; - if (!ship_has_engine_power(ship_p)) i++; - if (i >= 2) return; + int x = position[0]; + int y = position[1]; + float scale = 1.0; - // no shields, no shields gauge - if (Player_obj->flags[Object::Object_Flags::No_shields]) { - return; + if (config) { + std::tie(x, y, scale) = hud_config_convert_coord_sys(position[0], position[1], base_w, base_h); } - setGaugeColor(); + + // if at least two gauges are not shown, don't show any + if (!config) { + int i = 0; + if (!ship_has_energy_weapons(ship_p)) + i++; + if (Player_obj->flags[Object::Object_Flags::No_shields]) + i++; + if (!ship_has_engine_power(ship_p)) + i++; + if (i >= 2) + return; + + // no shields, no shields gauge + if (Player_obj->flags[Object::Object_Flags::No_shields]) { + return; + } + } + + setGaugeColor(HUD_C_NONE, config); // draw the letters for the gauge first, before any clipping occurs - renderPrintf(position[0] + Letter_offsets[0], position[1] + Letter_offsets[1], 1.0f, false, NOX("%c"), Letter); + int rx = position[0] + Letter_offsets[0]; + int ry = position[1] + Letter_offsets[1]; + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + renderPrintf(rx, ry, scale, config, NOX("%c"), Letter); // draw the gauge for the shield system - blitGauge(ship_p->shield_recharge_index); + int level = config ? 4 : ship_p->weapon_recharge_index; + rx = position[0]; + ry = position[1]; + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + blitGauge(level, rx, ry, scale, config); + + if (config) { + int bmw, bmh; + bm_get_info(Ets_bar.first_frame, &bmw, &bmh); + + hud_config_set_mouse_coords_ets(gauge_config, rx, rx + bmw, ry, ry + (bmh * 2) + 10); + } } HudGaugeEtsEngines::HudGaugeEtsEngines(): @@ -1146,33 +1270,67 @@ HudGaugeEts(HUD_OBJECT_ETS_ENGINES, (int)ENGINES) { } -void HudGaugeEtsEngines::render(float /*frametime*/, bool /*config*/) +void HudGaugeEtsEngines::render(float /*frametime*/, bool config) { - int i; - - ship* ship_p = &Ships[Player_obj->instance]; + ship* ship_p = nullptr; + if (!config) { + ship_p = &Ships[Player_obj->instance]; + } if ( Ets_bar.first_frame < 0 ) { return; } - // if at least two gauges are not shown, don't show any - i = 0; - if (!ship_has_energy_weapons(ship_p)) i++; - if (Player_obj->flags[Object::Object_Flags::No_shields]) i++; - if (!ship_has_engine_power(ship_p)) i++; - if (i >= 2) return; + int x = position[0]; + int y = position[1]; + float scale = 1.0; - // no engines, no engine gauge - if (!ship_has_engine_power(ship_p)) { - return; + if (config) { + std::tie(x, y, scale) = hud_config_convert_coord_sys(position[0], position[1], base_w, base_h); } - setGaugeColor(); + + // if at least two gauges are not shown, don't show any + if (!config) { + int i = 0; + if (!ship_has_energy_weapons(ship_p)) + i++; + if (Player_obj->flags[Object::Object_Flags::No_shields]) + i++; + if (!ship_has_engine_power(ship_p)) + i++; + if (i >= 2) + return; + + // no engines, no engine gauge + if (!ship_has_engine_power(ship_p)) { + return; + } + } + + setGaugeColor(HUD_C_NONE, config); // draw the letters for the gauge first, before any clipping occurs - renderPrintf(position[0] + Letter_offsets[0], position[1] + Letter_offsets[1], 1.0f, false, NOX("%c"), Letter); + int rx = position[0] + Letter_offsets[0]; + int ry = position[1] + Letter_offsets[1]; + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + renderPrintf(rx, ry, scale, config, NOX("%c"), Letter); // draw the gauge for the engine system - blitGauge(ship_p->engine_recharge_index); + int level = config ? 4 : ship_p->weapon_recharge_index; + rx = position[0]; + ry = position[1]; + if (config) { + std::tie(rx, ry) = hud_config_convert_coords(rx, ry, scale); + } + blitGauge(level, rx, ry, scale, config); + + if (config) { + int bmw, bmh; + bm_get_info(Ets_bar.first_frame, &bmw, &bmh); + + hud_config_set_mouse_coords_ets(gauge_config, rx, rx + bmw, ry, ry + (bmh * 2) + 10); + } } diff --git a/code/hud/hudets.h b/code/hud/hudets.h index be29657321..9320e7a867 100644 --- a/code/hud/hudets.h +++ b/code/hud/hudets.h @@ -79,7 +79,7 @@ public: void initLetter(char _letter); // obligatory PC Load Letter joke. (Swifty) void initBarHeight(int _ets_bar_h); void initBitmaps(char *fname); - void blitGauge(int index); + void blitGauge(int index, int ix, int iy, float scale, bool config); void render(float frametime, bool config = false) override; void pageIn() override; }; diff --git a/code/hud/hudlock.cpp b/code/hud/hudlock.cpp index d74a060446..073fa437f0 100644 --- a/code/hud/hudlock.cpp +++ b/code/hud/hudlock.cpp @@ -279,13 +279,26 @@ void HudGaugeLock::renderOld(float frametime) // lock_point_pos should be the world coordinates of the target being locked. Assuming all the // necessary locking calculations are done for this frame, this function will compute // where the indicator should be relative to the player's viewpoint and will render accordingly. -void HudGaugeLock::render(float frametime, bool /*config*/) +void HudGaugeLock::render(float frametime, bool config) { - size_t i; - lock_info *current_lock; + float scale = 1.0; - vertex lock_point; - int sx, sy; + // This gauge does not accept config settings so we don't have to render it right now. + // That may change in the future, in which case the code below can be restored. + if (config) { + // The coords don't really get converted here but we still get scale based on the screen size which we need + /* int x = 0, y = 0; + std::tie(x, y, scale) = hud_config_convert_coord_sys(position[0], position[1], base_w, base_h); + + int w; + int h; + // Will need actual coords for the below if we activate this gauge in config + hud_config_set_mouse_coords(gauge_config, x, x + w, y, y + h); + + setGaugeColor(HUD_C_NONE, config);*/ + + return; + } // check to see if there are any missile to fire.. we don't want to show the // lock indicator if there are missiles to fire. @@ -299,58 +312,59 @@ void HudGaugeLock::render(float frametime, bool /*config*/) gr_set_screen_scale(base_w, base_h); // go through all present lock indicators - for ( i = 0; i < Player_ship->missile_locks.size(); ++i ) { - current_lock = &Player_ship->missile_locks[i]; + for (auto& current_lock : Player_ship->missile_locks){ - if ( !current_lock->indicator_visible ) { + if ( !current_lock.indicator_visible ) { continue; } // Get the target's current position on the screen. If he's not on there, // we're not going to draw the lock indicator even if he's in front // of our ship, so bail out. - g3_rotate_vertex(&lock_point, ¤t_lock->world_pos); + vertex lock_point; + g3_rotate_vertex(&lock_point, ¤t_lock.world_pos); g3_project_vertex(&lock_point); if (lock_point.codes & PF_OVERFLOW) { continue; } - hud_set_iff_color(current_lock->obj); + hud_set_iff_color(current_lock.obj); // We have the coordinates of the lock indicator relative to the target in our "virtual frame" // so, we calculate where it should be drawn based on the player's viewpoint. - if ( current_lock->locked ) { + int sx, sy; + if ( current_lock.locked ) { sx = fl2i(lock_point.screen.xyw.x); sy = fl2i(lock_point.screen.xyw.y); gr_unsize_screen_pos(&sx, &sy); // show the rotating triangles if target is locked - renderLockTrianglesNew(sx, sy, frametime, current_lock); + renderLockTrianglesNew(sx, sy, frametime, ¤t_lock); } else { const float scaling_factor = (gr_screen.clip_center_x < gr_screen.clip_center_y) ? (gr_screen.clip_center_x / VIRTUAL_FRAME_HALF_WIDTH) : (gr_screen.clip_center_y / VIRTUAL_FRAME_HALF_HEIGHT); - sx = fl2i(lock_point.screen.xyw.x) - fl2i(i2fl(current_lock->current_target_sx - current_lock->indicator_x) * scaling_factor); - sy = fl2i(lock_point.screen.xyw.y) - fl2i(i2fl(current_lock->current_target_sy - current_lock->indicator_y) * scaling_factor); + sx = fl2i(lock_point.screen.xyw.x) - fl2i(i2fl(current_lock.current_target_sx - current_lock.indicator_x) * scaling_factor); + sy = fl2i(lock_point.screen.xyw.y) - fl2i(i2fl(current_lock.current_target_sy - current_lock.indicator_y) * scaling_factor); gr_unsize_screen_pos(&sx, &sy); } - Lock_gauge.sx = sx - Lock_gauge_half_w; - Lock_gauge.sy = sy - Lock_gauge_half_h; - if( current_lock->locked ){ - current_lock->lock_gauge_time_elapsed = 0.0f; - Lock_gauge.time_elapsed = current_lock->lock_gauge_time_elapsed; - hud_anim_render(&Lock_gauge, 0.0f, 1); + Lock_gauge.sx = sx - fl2i(Lock_gauge_half_w * scale); + Lock_gauge.sy = sy - fl2i(Lock_gauge_half_h * scale); + if( current_lock.locked ){ + current_lock.lock_gauge_time_elapsed = 0.0f; + Lock_gauge.time_elapsed = current_lock.lock_gauge_time_elapsed; + hud_anim_render(&Lock_gauge, 0.0f, 1, 1, 0, 0, GR_RESIZE_FULL, false, scale); } else { // manually track the animation time, since we may have more than one lock - current_lock->lock_gauge_time_elapsed += frametime; - if (current_lock->lock_gauge_time_elapsed > Lock_gauge.total_time) { - current_lock->lock_gauge_time_elapsed = 0.0f; + current_lock.lock_gauge_time_elapsed += frametime; + if (current_lock.lock_gauge_time_elapsed > Lock_gauge.total_time) { + current_lock.lock_gauge_time_elapsed = 0.0f; } - Lock_gauge.time_elapsed = current_lock->lock_gauge_time_elapsed; + Lock_gauge.time_elapsed = current_lock.lock_gauge_time_elapsed; - hud_anim_render(&Lock_gauge, 0.0f, 1); + hud_anim_render(&Lock_gauge, 0.0f, 1, 1, 0, 0, GR_RESIZE_FULL, false, scale); } }