Files
Goober5000andClaude Opus 4.6 3f85d6172a use std::move() for local variables that are copied but not reused (#7308)
* use std::move() for local variables that are copied but not reused

Addresses ~140 Coverity "Variable copied when it could be moved"
defects across 74 files.  Every std::move() targets a local variable
whose value is consumed by push_back, emplace, assignment, lambda
capture, or a function call and is never read again afterward.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>

* clang: use std::make_shared

* clang: use std::make_unique

* address feedback

---------

Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
2026-05-07 14:40:38 +09:00

663 lines
21 KiB
C++

/*
* Copyright (C) Volition, Inc. 1999. All rights reserved.
*
* All source code herein is the property of Volition, Inc. You may not sell
* or otherwise commercially exploit the source or things you created based on the
* source.
*
*/
#include "controlconfig/controlsconfig.h"
#include "freespace.h"
#include "gamehelp/gameplayhelp.h"
#include "gamesequence/gamesequence.h"
#include "gamesnd/gamesnd.h"
#include "globalincs/alphacolors.h"
#include "io/key.h"
#include "mission/missionmessage.h"
#include "missionui/missionscreencommon.h"
#include "sound/audiostr.h"
#include "ui/ui.h"
#include "weapon/weapon.h"
// text positioning constants
#define TITLE_Y 35
#define Y_START 70
#define X_OFFSET_1 70
// pixel offset for description of key from where key binding starts
// increased this from 193 to 250 to account for allowing multiple keys -Mjn
#define KEY_DESCRIPTION_OFFSET 250
// different gameplay help pages
enum : int {
// The first 9 are the basic retail pages
GP_HELP_BASIC_KEYS,
GP_HELP_MOVEMENT_KEYS,
GP_HELP_COMMON_TARGET_KEYS,
GP_HELP_ADVANCED_TARGET_KEYS,
GP_HELP_MESSAGING,
GP_HELP_WEAPON_KEYS,
GP_HELP_THROTTLE_AND_ETS_KEYS,
GP_HELP_VIEW_KEYS,
GP_HELP_MISC_KEYS,
// Plus one for multi only
GP_HELP_MULTI_KEYS,
// Any others defined here will have unique sections within the vector
// but will need special handling to display in the retail UI
GP_HELP_FUNCTION_KEYS,
First_available_section
};
#define GP_FIRST_SCREEN 0 // keep up to date
#define GP_LAST_SCREEN_SINGLE 8 // keep up to date
#define GP_LAST_SCREEN_MULTI 9 // keep up to date
// set this to GP_LAST_SCREEN_SINGLE or GP_LAST_SCREEN_MULTI based upon what game mode we're in
static int Gp_last_screen;
#define NUM_BUTTONS 3
#define PREVIOUS_PAGE_BUTTON 0
#define NEXT_PAGE_BUTTON 1
#define CONTINUE_BUTTON 2
struct gameplay_help_buttons {
const char *filename;
int x, y;
int hotspot;
int tab;
int flags;
UI_BUTTON button; // because we have a class inside this struct, we need the constructor below..
gameplay_help_buttons(const char *name, int x1, int y1, int h) : filename(name), x(x1), y(y1), hotspot(h) {}
};
static gameplay_help_buttons Buttons[GR_NUM_RESOLUTIONS][NUM_BUTTONS] = {
//XSTR:OFF
{
gameplay_help_buttons("F1B_00", 15, 389, 0),
gameplay_help_buttons("F1B_01", 60, 389, 1),
gameplay_help_buttons("F1B_02", 574, 431, 2)
},
{
gameplay_help_buttons("2_F1B_00", 24, 622, 0),
gameplay_help_buttons("2_F1B_01", 96, 622, 1),
gameplay_help_buttons("2_F1B_02", 919, 689, 2)
},
//XSTR:ON
};
#define GAME_HELP_NUM_TEXT 2
static UI_XSTR Game_help_text[GR_NUM_RESOLUTIONS][GAME_HELP_NUM_TEXT] = {
{ // GR_640
{ "Press ESC to return to the game", 1441, 263, 389, UI_XSTR_COLOR_GREEN, -1, NULL },
{ "Continue", 1069, 571, 413, UI_XSTR_COLOR_GREEN, -1, &Buttons[gr_screen.res][CONTINUE_BUTTON].button }
},
{ // GR_1024
{ "Press ESC to return to the game", 1441, 421, 622, UI_XSTR_COLOR_GREEN, -1, NULL },
{ "Continue", 1069, 928, 663, UI_XSTR_COLOR_GREEN, -1, &Buttons[gr_screen.res][CONTINUE_BUTTON].button }
}
};
static const char *Game_help_filename[GR_NUM_RESOLUTIONS] = {
"F1",
"2_F1"
};
static const char *Game_help_mask_filename[GR_NUM_RESOLUTIONS] = {
"F1-m",
"2_F1-m"
};
static UI_WINDOW Ui_window;
static int Background_bitmap;
static int Gameplay_help_inited = 0;
static int Current_help_page;
SCP_vector<gameplay_help_section> Help_text;
void gameplay_help_init_control_line(int id, gameplay_help_section &thisHelp)
{
char buf[256];
auto ci = &Control_config[id];
// do not draw if a mod has disabled this control --wookieejedi
if (ci->disabled) {
return;
}
buf[0] = 0;
strcpy_s(buf, ci->first.textify().c_str());
if (!ci->second.empty()) {
strcat_s(buf, XSTR(", ", 129));
strcat_s(buf, ci->second.textify().c_str());
}
if (ci->empty()) {
strcpy_s(buf, XSTR("no binding", 130));
}
thisHelp.key.push_back(buf);
thisHelp.text.push_back(XSTR(ci->text.c_str(), CONTROL_CONFIG_XSTR + id));
}
void gameplay_help_init_control_line_raw(const char* control_text, const char* control_description, gameplay_help_section &thisHelp)
{
thisHelp.key.push_back(control_text);
thisHelp.text.push_back(control_description);
}
// displays the given help key and text at the specified
// x and y coordinates
void gameplay_help_blit_help_text(int x, int y, const SCP_string *control_text, const SCP_string *control_description)
{
gr_string(x, y, control_text->c_str(), GR_RESIZE_MENU);
gr_string(x + KEY_DESCRIPTION_OFFSET, y, control_description->c_str(), GR_RESIZE_MENU);
}
// displays a help section header at the specified y coordinate and an x coordinate
// calculated from the header string's length
void gameplay_help_blit_header_text(int y_offset, const SCP_string *header)
{
gr_set_color_fast(&Color_bright);
int w;
gr_get_string_size(&w, nullptr, header->c_str());
gr_printf_menu((gr_screen.clip_width - w) / 2, y_offset, "%s", header->c_str());
gr_set_color_fast(&Color_normal);
}
// game_play_help_set_title() will display the title for the help screen and
// set the font for the rest of the screen
void gameplay_help_set_title(const SCP_string *title)
{
int sy=TITLE_Y;
char buf[128];
gr_set_color_fast(&Color_bright);
int w;
gr_get_string_size(&w, nullptr, title->c_str());
gr_printf_menu((gr_screen.clip_width_unscaled - w) / 2,sy,"%s", title->c_str());
sprintf(buf, XSTR("Page %d of %d", 132), Current_help_page + 1, Gp_last_screen + 1);
gr_get_string_size(&w, NULL, buf);
gr_printf_menu((gr_screen.clip_width_unscaled - w) / 2, sy + gr_get_font_height() + 2, "%s", buf);
gr_set_color_fast(&Color_normal);
}
// Inits all the gameplay help text and returns it
// in a nice organized vector of help sections
SCP_vector<gameplay_help_section> gameplay_help_init_text()
{
SCP_vector<gameplay_help_section> complete_help_text;
for (int i = 0; i < First_available_section; i++) {
gameplay_help_section thisHelp;
switch (i) {
case GP_HELP_BASIC_KEYS:
thisHelp.title = XSTR("Basic Keys", 133);
thisHelp.header = "";
gameplay_help_init_control_line(END_MISSION, thisHelp);
gameplay_help_init_control_line(FIRE_PRIMARY, thisHelp);
gameplay_help_init_control_line(MAX_THROTTLE, thisHelp);
gameplay_help_init_control_line(ZERO_THROTTLE, thisHelp);
gameplay_help_init_control_line(TARGET_NEXT, thisHelp);
gameplay_help_init_control_line(TARGET_PREV, thisHelp);
gameplay_help_init_control_line(TOGGLE_AUTO_TARGETING, thisHelp);
break;
case GP_HELP_MOVEMENT_KEYS:
thisHelp.title = XSTR("Movement Keys", 147);
thisHelp.header = "";
gameplay_help_init_control_line(FORWARD_THRUST, thisHelp);
gameplay_help_init_control_line(MAX_THROTTLE, thisHelp);
gameplay_help_init_control_line(ONE_THIRD_THROTTLE, thisHelp);
gameplay_help_init_control_line(TWO_THIRDS_THROTTLE, thisHelp);
gameplay_help_init_control_line(MINUS_5_PERCENT_THROTTLE, thisHelp);
gameplay_help_init_control_line(PLUS_5_PERCENT_THROTTLE, thisHelp);
gameplay_help_init_control_line(ZERO_THROTTLE, thisHelp);
gameplay_help_init_control_line(AFTERBURNER, thisHelp);
gameplay_help_init_control_line(REVERSE_THRUST, thisHelp);
gameplay_help_init_control_line(PITCH_FORWARD, thisHelp);
gameplay_help_init_control_line(PITCH_BACK, thisHelp);
gameplay_help_init_control_line(YAW_LEFT, thisHelp);
gameplay_help_init_control_line(YAW_RIGHT, thisHelp);
gameplay_help_init_control_line(BANK_LEFT, thisHelp);
gameplay_help_init_control_line(BANK_RIGHT, thisHelp);
gameplay_help_init_control_line(BANK_WHEN_PRESSED, thisHelp);
break;
case GP_HELP_COMMON_TARGET_KEYS:
thisHelp.title = XSTR("Basic Targeting Keys", 148);
thisHelp.header = "";
gameplay_help_init_control_line(TARGET_NEXT, thisHelp);
gameplay_help_init_control_line(TARGET_PREV, thisHelp);
gameplay_help_init_control_line(TOGGLE_AUTO_TARGETING, thisHelp);
gameplay_help_init_control_line(TARGET_SHIP_IN_RETICLE, thisHelp);
gameplay_help_init_control_line(TARGET_NEXT_CLOSEST_HOSTILE, thisHelp);
gameplay_help_init_control_line(TARGET_PREV_CLOSEST_HOSTILE, thisHelp);
gameplay_help_init_control_line(TARGET_NEXT_CLOSEST_FRIENDLY, thisHelp);
gameplay_help_init_control_line(TARGET_PREV_CLOSEST_FRIENDLY, thisHelp);
gameplay_help_init_control_line(TARGET_NEXT_SUBOBJECT, thisHelp);
gameplay_help_init_control_line(TARGET_PREV_SUBOBJECT, thisHelp);
gameplay_help_init_control_line(TARGET_SUBOBJECT_IN_RETICLE, thisHelp);
gameplay_help_init_control_line(MATCH_TARGET_SPEED, thisHelp);
gameplay_help_init_control_line(TOGGLE_AUTO_MATCH_TARGET_SPEED, thisHelp);
break;
case GP_HELP_ADVANCED_TARGET_KEYS:
thisHelp.title = XSTR("Advanced Targeting Keys", 149);
thisHelp.header = "";
gameplay_help_init_control_line(TARGET_CLOSEST_SHIP_ATTACKING_SELF, thisHelp);
gameplay_help_init_control_line(TARGET_CLOSEST_SHIP_ATTACKING_TARGET, thisHelp);
gameplay_help_init_control_line(TARGET_LAST_TRANMISSION_SENDER, thisHelp);
gameplay_help_init_control_line(TARGET_TARGETS_TARGET, thisHelp);
gameplay_help_init_control_line(TARGET_NEXT_ESCORT_SHIP, thisHelp);
gameplay_help_init_control_line(TARGET_CLOSEST_REPAIR_SHIP, thisHelp);
gameplay_help_init_control_line(TARGET_NEXT_UNINSPECTED_CARGO, thisHelp);
gameplay_help_init_control_line(TARGET_PREV_UNINSPECTED_CARGO, thisHelp);
gameplay_help_init_control_line(TARGET_NEWEST_SHIP, thisHelp);
gameplay_help_init_control_line(TARGET_NEXT_BOMB, thisHelp);
gameplay_help_init_control_line(TARGET_PREV_BOMB, thisHelp);
gameplay_help_init_control_line(STOP_TARGETING_SHIP, thisHelp);
gameplay_help_init_control_line(TARGET_NEXT_LIVE_TURRET, thisHelp);
gameplay_help_init_control_line(TARGET_PREV_LIVE_TURRET, thisHelp);
gameplay_help_init_control_line(STOP_TARGETING_SUBSYSTEM, thisHelp);
gameplay_help_init_control_line_raw(XSTR("F5...F12", 143), XSTR("Select target assigned to that hotkey", 150), thisHelp);
gameplay_help_init_control_line_raw(XSTR("Shift-F5...F12", 151), XSTR("Add/remove target from that hotkey", 152), thisHelp);
gameplay_help_init_control_line_raw(XSTR("Alt-Shift-F5...F12", 153), XSTR("Clear that hotkey", 154), thisHelp);
break;
case GP_HELP_MESSAGING:
thisHelp.title = XSTR("Messaging Keys", 155);
thisHelp.header = "";
gameplay_help_init_control_line(SQUADMSG_MENU, thisHelp);
gameplay_help_init_control_line(REARM_MESSAGE, thisHelp);
gameplay_help_init_control_line(ATTACK_MESSAGE, thisHelp);
gameplay_help_init_control_line(DISARM_MESSAGE, thisHelp);
gameplay_help_init_control_line(DISABLE_MESSAGE, thisHelp);
gameplay_help_init_control_line(CAPTURE_MESSAGE, thisHelp);
gameplay_help_init_control_line(ENGAGE_MESSAGE, thisHelp);
gameplay_help_init_control_line(FORM_MESSAGE, thisHelp);
gameplay_help_init_control_line(IGNORE_MESSAGE, thisHelp);
gameplay_help_init_control_line(PROTECT_MESSAGE, thisHelp);
gameplay_help_init_control_line(COVER_MESSAGE, thisHelp);
gameplay_help_init_control_line(WARP_MESSAGE, thisHelp);
gameplay_help_init_control_line_raw(XSTR("F5...F12", 143),
XSTR("send specified order to these target(s)", 156),
thisHelp);
break;
case GP_HELP_WEAPON_KEYS:
thisHelp.title = XSTR("Weapon Keys", 157);
thisHelp.header = "";
gameplay_help_init_control_line(FIRE_PRIMARY, thisHelp);
gameplay_help_init_control_line(FIRE_SECONDARY, thisHelp);
gameplay_help_init_control_line(CYCLE_NEXT_PRIMARY, thisHelp);
gameplay_help_init_control_line(CYCLE_PREV_PRIMARY, thisHelp);
gameplay_help_init_control_line(CYCLE_SECONDARY, thisHelp);
gameplay_help_init_control_line(CYCLE_NUM_MISSLES, thisHelp);
gameplay_help_init_control_line(LAUNCH_COUNTERMEASURE, thisHelp);
break;
case GP_HELP_THROTTLE_AND_ETS_KEYS:
thisHelp.title = XSTR("Energy Management Keys", 158);
thisHelp.header = "";
gameplay_help_init_control_line(SHIELD_EQUALIZE, thisHelp);
gameplay_help_init_control_line(SHIELD_XFER_TOP, thisHelp);
gameplay_help_init_control_line(SHIELD_XFER_BOTTOM, thisHelp);
gameplay_help_init_control_line(SHIELD_XFER_LEFT, thisHelp);
gameplay_help_init_control_line(SHIELD_XFER_RIGHT, thisHelp);
gameplay_help_init_control_line(INCREASE_WEAPON, thisHelp);
gameplay_help_init_control_line(DECREASE_WEAPON, thisHelp);
gameplay_help_init_control_line(INCREASE_SHIELD, thisHelp);
gameplay_help_init_control_line(DECREASE_SHIELD, thisHelp);
gameplay_help_init_control_line(INCREASE_ENGINE, thisHelp);
gameplay_help_init_control_line(DECREASE_ENGINE, thisHelp);
gameplay_help_init_control_line(ETS_EQUALIZE, thisHelp);
/*
gameplay_help_init_control_line(XFER_LASER, thisHelp);
gameplay_help_init_control_line(XFER_SHIELD, thisHelp);
*/
break;
case GP_HELP_MISC_KEYS:
thisHelp.title = XSTR("Miscellaneous Keys", 159);
thisHelp.header = "";
// ending mission
gameplay_help_init_control_line(END_MISSION, thisHelp);
gameplay_help_init_control_line_raw(XSTR("ESC", 160), XSTR("invoke abort mission popup", 161), thisHelp);
// time compression
gameplay_help_init_control_line(TIME_SPEED_UP, thisHelp);
gameplay_help_init_control_line(TIME_SLOW_DOWN, thisHelp);
// radar keys
gameplay_help_init_control_line(RADAR_RANGE_CYCLE, thisHelp);
// escort view keys
gameplay_help_init_control_line(ADD_REMOVE_ESCORT, thisHelp);
gameplay_help_init_control_line(ESCORT_CLEAR, thisHelp);
// Pause, Print Screenshot
gameplay_help_init_control_line_raw(XSTR("Pause", 162), XSTR("pause game", 163), thisHelp);
gameplay_help_init_control_line_raw(XSTR("Print Scrn", 164), XSTR("take screen shot", 165), thisHelp);
break;
case GP_HELP_VIEW_KEYS:
thisHelp.title = XSTR("View Keys", 166);
thisHelp.header = "";
gameplay_help_init_control_line(PADLOCK_UP, thisHelp);
gameplay_help_init_control_line(PADLOCK_DOWN, thisHelp);
gameplay_help_init_control_line(PADLOCK_LEFT, thisHelp);
gameplay_help_init_control_line(PADLOCK_RIGHT, thisHelp);
gameplay_help_init_control_line(VIEW_CHASE, thisHelp);
gameplay_help_init_control_line(VIEW_EXTERNAL, thisHelp);
gameplay_help_init_control_line(VIEW_EXTERNAL_TOGGLE_CAMERA_LOCK, thisHelp);
gameplay_help_init_control_line(VIEW_SLEW, thisHelp);
gameplay_help_init_control_line(VIEW_DIST_INCREASE, thisHelp);
gameplay_help_init_control_line(VIEW_DIST_DECREASE, thisHelp);
gameplay_help_init_control_line(VIEW_CENTER, thisHelp);
gameplay_help_init_control_line(VIEW_OTHER_SHIP, thisHelp);
break;
case GP_HELP_MULTI_KEYS:
thisHelp.title = XSTR("Multiplayer Keys", 167);
thisHelp.header = XSTR("Ingame messaging keys (tap for text, hold for voice)", 168);
gameplay_help_init_control_line(MULTI_MESSAGE_ALL, thisHelp);
gameplay_help_init_control_line(MULTI_MESSAGE_FRIENDLY, thisHelp);
gameplay_help_init_control_line(MULTI_MESSAGE_HOSTILE, thisHelp);
gameplay_help_init_control_line(MULTI_MESSAGE_TARGET, thisHelp);
break;
case GP_HELP_FUNCTION_KEYS:
thisHelp.title = XSTR("Function Keys", 134);
thisHelp.header = "";
gameplay_help_init_control_line_raw(XSTR("F1", 135), XSTR("context-sensitive help", 136), thisHelp);
gameplay_help_init_control_line_raw(XSTR("F2", 137),
XSTR("options screen (available anywhere in game)", 138),
thisHelp);
gameplay_help_init_control_line_raw(XSTR("F3", 139), XSTR("hotkey assignment", 140), thisHelp);
gameplay_help_init_control_line_raw(XSTR("F4", 141), XSTR("HUD message scroll-back", 142), thisHelp);
gameplay_help_init_control_line_raw(XSTR("F5...F12", 143), XSTR("hotkeys", 144), thisHelp);
gameplay_help_init_control_line_raw(XSTR("Shift-Esc", 145),
XSTR("quit FreeSpace 2 immediately", 146),
thisHelp);
break;
default:
continue;
}
complete_help_text.push_back(std::move(thisHelp));
}
return complete_help_text;
}
// called once when the gameplay help state is entered
void gameplay_help_init()
{
int i;
gameplay_help_buttons *b;
if ( Gameplay_help_inited ) {
return;
}
// init all the help text
Help_text.clear(); //Make sure the array is empty before we start.
Help_text = gameplay_help_init_text();
common_set_interface_palette("InterfacePalette"); // set the interface palette
Ui_window.create(0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0);
Ui_window.set_mask_bmap(Game_help_mask_filename[gr_screen.res]);
for (i=0; i<NUM_BUTTONS; i++) {
b = &Buttons[gr_screen.res][i];
b->button.create(&Ui_window, "", b->x, b->y, 60, 30, 0, 1);
// set up callback for when a mouse first goes over a button
b->button.set_highlight_action(common_play_highlight_sound);
b->button.set_bmaps(b->filename);
b->button.link_hotspot(b->hotspot);
}
// add all xstrs
for (i=0; i<GAME_HELP_NUM_TEXT; i++)
{
Ui_window.add_XSTR(&Game_help_text[gr_screen.res][i]);
}
// set the proper last screen # based upon game mode
if(Game_mode & GM_MULTIPLAYER){
Gp_last_screen = GP_LAST_SCREEN_MULTI;
} else {
Gp_last_screen = GP_LAST_SCREEN_SINGLE;
}
// setup hotkeys so lights flash when keys are pressed
Buttons[gr_screen.res][CONTINUE_BUTTON].button.set_hotkey(KEY_CTRLED | KEY_ENTER);
Buttons[gr_screen.res][PREVIOUS_PAGE_BUTTON].button.set_hotkey(KEY_LEFT);
Buttons[gr_screen.res][NEXT_PAGE_BUTTON].button.set_hotkey(KEY_RIGHT);
Background_bitmap = bm_load(Game_help_filename[gr_screen.res]);
Current_help_page = GP_FIRST_SCREEN;
Gameplay_help_inited = 1;
}
// called when moving to the previous help page
void gameplay_help_goto_prev_screen()
{
Current_help_page--;
if (Current_help_page < GP_FIRST_SCREEN) {
Current_help_page = Gp_last_screen;
}
gamesnd_play_iface(InterfaceSounds::SWITCH_SCREENS);
}
// called when proceeding to the next help page
void gameplay_help_goto_next_screen()
{
Current_help_page++;
if (Current_help_page > Gp_last_screen) {
Current_help_page = GP_FIRST_SCREEN;
}
gamesnd_play_iface(InterfaceSounds::SWITCH_SCREENS);
}
// called when the screen is exited
void gameplay_help_leave()
{
// unpause all game sounds
weapon_unpause_sounds();
audiostream_unpause_all();
message_resume_all();
gameseq_post_event(GS_EVENT_PREVIOUS_STATE);
game_flush();
}
// deal with a keypress on the gameplay help screen
void gameplay_help_process_key(int k)
{
switch ( k ) {
case KEY_ESC:
gameplay_help_leave();
break;
case KEY_ENTER:
case KEY_SPACEBAR:
case KEY_TAB:
//gameplay_help_goto_next_screen();
Buttons[gr_screen.res][NEXT_PAGE_BUTTON].button.press_button();
break;
case KEY_SHIFTED | KEY_TAB:
Buttons[gr_screen.res][PREVIOUS_PAGE_BUTTON].button.press_button();
// gameplay_help_goto_prev_screen();
break;
default:
break;
} // end switch
}
// deal with buttons being pressed on the gameplay help screen
void gameplay_help_button_pressed(int n)
{
switch (n) {
case PREVIOUS_PAGE_BUTTON:
gameplay_help_goto_prev_screen();
break;
case NEXT_PAGE_BUTTON:
gameplay_help_goto_next_screen();
break;
case CONTINUE_BUTTON:
gameplay_help_leave();
gamesnd_play_iface(InterfaceSounds::COMMIT_PRESSED);
break;
default:
Int3();
break;
}
}
// Draw the help text onto the screen
void gameplay_help_draw_text()
{
int x_offset, y_offset, separation;
separation = gr_get_font_height() + 3;
gameplay_help_section thisHelp = Help_text[Current_help_page];
gameplay_help_set_title(&thisHelp.title);
x_offset = X_OFFSET_1;
y_offset = Y_START;
// if we have a header then display it
if (thisHelp.header.length() > 0) {
gameplay_help_blit_header_text(y_offset, &thisHelp.header);
y_offset += separation;
}
// blit help text for each key
for (int i = 0; i < (int)thisHelp.key.size(); i++) {
y_offset += separation;
gameplay_help_blit_help_text(x_offset, y_offset, &thisHelp.key[i], &thisHelp.text[i]);
}
// Special handling of function keys to display on the same page as the basic keys
if (Current_help_page == GP_HELP_BASIC_KEYS) {
y_offset += separation;
y_offset += separation;
thisHelp = Help_text[GP_HELP_FUNCTION_KEYS];
gameplay_help_blit_header_text(y_offset, &thisHelp.title);
y_offset += separation;
y_offset += separation;
// blit help text for each key
for (int i = 0; i < (int)thisHelp.key.size(); i++) {
y_offset += separation;
gameplay_help_blit_help_text(x_offset, y_offset, &thisHelp.key[i], &thisHelp.text[i]);
}
}
}
// gameplay_help_do_frame() is the function that displays help when acutally playing the game
void gameplay_help_do_frame(float /*frametime*/)
{
int i, k;
// ensure the gameplay help interface has been initialized
if (!Gameplay_help_inited) {
Int3();
return;
}
// make sure game sounds are paused
weapon_pause_sounds();
audiostream_pause_all();
message_pause_all();
k = Ui_window.process() & ~KEY_DEBUGGED;
gameplay_help_process_key(k);
for (i=0; i<NUM_BUTTONS; i++){
if (Buttons[gr_screen.res][i].button.pressed()){
gameplay_help_button_pressed(i);
}
}
GR_MAYBE_CLEAR_RES(Background_bitmap);
if (Background_bitmap >= 0) {
gr_set_bitmap(Background_bitmap);
gr_bitmap(0, 0, GR_RESIZE_MENU);
}
Ui_window.draw();
gameplay_help_draw_text();
gr_flip();
}