Skip to content

Commit ef73e25

Browse files
committed
unlimited mission titles
Some code refactoring to allow mission titles to be strings of any length. Titles that are too long to actually display (based on string width) will be visibly truncated using `font::force_fit_string`, but the underlying title will not be affected. Multiplayer is still subject to the 31-character length limit, so titles sent over the network will still have characters truncated. Also removes some redundant calls to `gr_get_string_size`, since `font::force_fit_string` returns the fitted string width.
1 parent 1cbfb34 commit ef73e25

23 files changed

Lines changed: 76 additions & 78 deletions

code/controlconfig/controlsconfig.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2724,8 +2724,7 @@ void control_config_do_frame(float frametime)
27242724
strcpy_s(buf, Control_config[i].text.c_str());
27252725
}
27262726

2727-
font::force_fit_string(buf, 255, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
2728-
gr_get_string_size(&w, NULL, buf);
2727+
w = font::force_fit_string(buf, 255, Conflict_wnd_coords[gr_screen.res][CONTROL_W_COORD]);
27292728
gr_printf_menu(x - w / 2, y, "%s", buf);
27302729

27312730
} else if (*bound_string) {

code/libs/discord/discord.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ SCP_string get_details()
6868
}
6969

7070
if (has_campaign && in_mission) {
71-
sprintf(res, "%s: %s", get_current_campaign_name().c_str(), The_mission.name);
71+
sprintf(res, "%s: %s", get_current_campaign_name().c_str(), The_mission.name.c_str());
7272
} else if (has_campaign) {
7373
sprintf(res, "Campaign %s", get_current_campaign_name().c_str());
7474
} else if (in_mission) {

code/menuui/readyroom.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,7 +493,7 @@ int build_standalone_mission_list_do_frame(bool API_Access)
493493
Lcl_unexpected_tstring_check = nullptr;
494494

495495
if (condition) {
496-
Standalone_mission_names[Num_standalone_missions_with_info] = vm_strdup(The_mission.name);
496+
Standalone_mission_names[Num_standalone_missions_with_info] = vm_strdup(The_mission.name.c_str());
497497
Standalone_mission_flags[Num_standalone_missions_with_info] = The_mission.game_type;
498498
int y = Num_lines * (font_height + 2);
499499

@@ -565,7 +565,7 @@ int build_campaign_mission_list_do_frame(bool API_Access)
565565
auto filename = Campaign.missions[Num_campaign_missions_with_info].name;
566566

567567
// add to list
568-
Campaign_mission_names[Num_campaign_missions_with_info] = vm_strdup(The_mission.name);
568+
Campaign_mission_names[Num_campaign_missions_with_info] = vm_strdup(The_mission.name.c_str());
569569
Campaign_mission_flags[Num_campaign_missions_with_info] = The_mission.game_type;
570570
int y = valid_missions_with_info * (font_height + 2);
571571

code/mission/missionparse.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ void parse_mission_info(mission *pm, bool basic = false)
787787
throw parse::VersionException("Mission requires version " + gameversion::format_version(pm->required_fso_version), pm->required_fso_version);
788788

789789
required_string("$Name:");
790-
stuff_string(pm->name, F_NAME, NAME_LENGTH);
790+
stuff_string(pm->name, F_NAME);
791791

792792
required_string("$Author:");
793793
stuff_string(pm->author, F_NAME);
@@ -1050,7 +1050,7 @@ void parse_mission_info(mission *pm, bool basic = false)
10501050
if (index >= 0)
10511051
The_mission.ai_profile = &Ai_profiles[index];
10521052
else
1053-
WarningEx(LOCATION, "Mission: %s\nUnknown AI profile %s!", pm->name, temp );
1053+
WarningEx(LOCATION, "Mission: %s\nUnknown AI profile %s!", pm->name.c_str(), temp );
10541054
}
10551055

10561056
if (optional_string("$Lighting Profile:"))
@@ -1232,7 +1232,7 @@ void parse_player_info2(mission *pm)
12321232
stuff_string(str, F_NAME, NAME_LENGTH);
12331233
ptr->default_ship = ship_info_lookup(str);
12341234
if (-1 == ptr->default_ship) {
1235-
WarningEx(LOCATION, "Mission: %s\nUnknown default ship %s! Defaulting to %s.", pm->name, str, Ship_info[ptr->ship_list[0]].name );
1235+
WarningEx(LOCATION, "Mission: %s\nUnknown default ship %s! Defaulting to %s.", pm->name.c_str(), str, Ship_info[ptr->ship_list[0]].name );
12361236
ptr->default_ship = ptr->ship_list[0]; // default to 1st in list
12371237
}
12381238
// see if the player's default ship is an allowable ship (campaign only). If not, then what
@@ -1245,7 +1245,7 @@ void parse_player_info2(mission *pm)
12451245
break;
12461246
}
12471247
}
1248-
Assertion( i < ship_info_size(), "Mission: %s: Could not find a valid default ship.\n", pm->name );
1248+
Assertion( i < ship_info_size(), "Mission: %s: Could not find a valid default ship.\n", pm->name.c_str() );
12491249
}
12501250
}
12511251
}
@@ -3391,7 +3391,7 @@ int parse_object(mission *pm, int /*flag*/, p_object *p_objp)
33913391
// try and find the alternate name
33923392
p_objp->alt_type_index = mission_parse_lookup_alt(name);
33933393
if(p_objp->alt_type_index < 0)
3394-
WarningEx(LOCATION, "Mission %s\nError looking up alternate ship type name %s!\n", pm->name, name);
3394+
WarningEx(LOCATION, "Mission %s\nError looking up alternate ship type name %s!\n", pm->name.c_str(), name);
33953395
else
33963396
mprintf(("Using alternate ship type name: %s\n", name));
33973397
}
@@ -3405,7 +3405,7 @@ int parse_object(mission *pm, int /*flag*/, p_object *p_objp)
34053405
// try and find the callsign
34063406
p_objp->callsign_index = mission_parse_lookup_callsign(name);
34073407
if(p_objp->callsign_index < 0)
3408-
WarningEx(LOCATION, "Mission %s\nError looking up callsign %s!\n", pm->name, name);
3408+
WarningEx(LOCATION, "Mission %s\nError looking up callsign %s!\n", pm->name.c_str(), name);
34093409
else
34103410
mprintf(("Using callsign: %s\n", name));
34113411
}
@@ -6310,7 +6310,7 @@ void parse_bitmaps(mission *pm)
63106310
}
63116311

63126312
if (z == NUM_NEBULAS)
6313-
WarningEx(LOCATION, "Mission %s\nUnknown nebula %s!", pm->name, str);
6313+
WarningEx(LOCATION, "Mission %s\nUnknown nebula %s!", pm->name.c_str(), str);
63146314

63156315
if (optional_string("+Color:")) {
63166316
stuff_string(str, F_NAME, MAX_FILENAME_LEN);
@@ -6323,7 +6323,7 @@ void parse_bitmaps(mission *pm)
63236323
}
63246324

63256325
if (z == NUM_NEBULA_COLORS)
6326-
WarningEx(LOCATION, "Mission %s\nUnknown nebula color %s!", pm->name, str);
6326+
WarningEx(LOCATION, "Mission %s\nUnknown nebula color %s!", pm->name.c_str(), str);
63276327

63286328
if (optional_string("+Pitch:")){
63296329
stuff_int(&Nebula_pitch);
@@ -6421,7 +6421,7 @@ void parse_asteroid_fields(mission *pm)
64216421
if (subtype >= 0) {
64226422
Asteroid_field.field_debris_type.push_back(subtype);
64236423
} else {
6424-
WarningEx(LOCATION, "Mission %s\n Invalid asteroid debris %s!", pm->name, ast_name.c_str());
6424+
WarningEx(LOCATION, "Mission %s\n Invalid asteroid debris %s!", pm->name.c_str(), ast_name.c_str());
64256425
}
64266426
}
64276427

@@ -6473,7 +6473,7 @@ void parse_asteroid_fields(mission *pm)
64736473
if (valid){
64746474
Asteroid_field.field_asteroid_type.push_back(std::move(ast_name));
64756475
} else {
6476-
WarningEx(LOCATION, "Mission %s\n Invalid asteroid %s!", pm->name, ast_name.c_str());
6476+
WarningEx(LOCATION, "Mission %s\n Invalid asteroid %s!", pm->name.c_str(), ast_name.c_str());
64776477
}
64786478
}
64796479
}
@@ -6853,7 +6853,7 @@ bool parse_mission(mission *pm, int flags)
68536853
popup(PF_TITLE_BIG | PF_TITLE_RED | PF_USE_AFFIRMATIVE_ICON | PF_NO_NETWORKING, 1, POPUP_OK, text);
68546854
}
68556855

6856-
log_printf(LOGFILE_EVENT_LOG, "Mission %s loaded.\n", pm->name);
6856+
log_printf(LOGFILE_EVENT_LOG, "Mission %s loaded.\n", pm->name.c_str());
68576857

68586858
// success
68596859
return true;
@@ -7203,8 +7203,8 @@ int get_mission_info(const char *filename, mission *mission_p, bool basic, bool
72037203

72047204
void mission::Reset()
72057205
{
7206-
name[ 0 ] = '\0';
7207-
author = "";
7206+
name.clear();
7207+
author.clear();
72087208
required_fso_version = LEGACY_MISSION_VERSION;
72097209
created[ 0 ] = '\0';
72107210
modified[ 0 ] = '\0';

code/mission/missionparse.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -185,7 +185,7 @@ struct parse_object_flag_description {
185185
};
186186

187187
typedef struct mission {
188-
char name[NAME_LENGTH];
188+
SCP_string name;
189189
SCP_string author;
190190
gameversion::version required_fso_version;
191191
char created[DATE_TIME_LENGTH];

code/missioneditor/missionsave.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2496,7 +2496,7 @@ int Fred_mission_save::save_mission_info()
24962496
// XSTR
24972497
required_string_fred("$Name:");
24982498
parse_comments();
2499-
fout_ext(" ", "%s", The_mission.name);
2499+
fout_ext(" ", "%s", The_mission.name.c_str());
25002500

25012501
required_string_fred("$Author:");
25022502
parse_comments();

code/missionui/missionbrief.cpp

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,10 @@ UI_XSTR Brief_select_text[GR_NUM_RESOLUTIONS][BRIEF_SELECT_NUM_TEXT] = {
290290
};
291291

292292
// coordinates for briefing title -- the x value is for the RIGHT side of the text
293-
static int Title_coords[GR_NUM_RESOLUTIONS][2] = {
294-
{575, 117}, // GR_640
295-
{918, 194} // GR_1024
293+
// third coord is max width of area for it to fit into (it is force fit there)
294+
static int Title_coords[GR_NUM_RESOLUTIONS][3] = {
295+
{575, 117, 370}, // GR_640
296+
{918, 194, 588} // GR_1024
296297
};
297298

298299
// coordinates for briefing title in multiplayer briefings -- the x value is for the LEFT side of the text
@@ -1158,7 +1159,7 @@ void brief_render(float frametime, bool api_access)
11581159
gr_printf_menu((gr_screen.clip_width_unscaled - w) / 2,200,XSTR( "No Briefing exists for mission: %s", 430), Game_current_mission_filename);
11591160

11601161
#ifndef NDEBUG
1161-
gr_get_string_size(&w, &h, The_mission.name);
1162+
gr_get_string_size(&w, &h, The_mission.name.c_str());
11621163
gr_set_color_fast(&Color_normal);
11631164
SCP_string debugText;
11641165
sprintf(debugText, NOX("[filename: %s, last mod: %s]"), Mission_filename, The_mission.modified);
@@ -1211,17 +1212,20 @@ void brief_render(float frametime, bool api_access)
12111212
gr_printf_menu(Brief_bmap_coords[gr_screen.res][0], Brief_bmap_coords[gr_screen.res][1]-title_y_offset, NOX("[name: %s, mod: %s]"), Mission_filename, The_mission.modified);
12121213
#endif
12131214

1215+
// force-fit mission title if necessary
1216+
const size_t max_buf_len = 255;
1217+
char buf[max_buf_len + 1];
1218+
strncpy(buf, The_mission.name.c_str(), max_buf_len);
1219+
buf[max_buf_len] = '\0';
1220+
const int max_coords_width = (Game_mode & GM_MULTIPLAYER) ? Title_coords_multi[gr_screen.res][2] : Title_coords[gr_screen.res][2];
1221+
w = font::force_fit_string(buf, max_buf_len, max_coords_width);
1222+
12141223
// output mission title
12151224
gr_set_color_fast(&Color_bright_white);
1216-
12171225
if (Game_mode & GM_MULTIPLAYER) {
1218-
char buf[256];
1219-
strncpy(buf, The_mission.name, 255);
1220-
font::force_fit_string(buf, 255, Title_coords_multi[gr_screen.res][2]);
12211226
gr_string(Title_coords_multi[gr_screen.res][0], Title_coords_multi[gr_screen.res][1], buf, GR_RESIZE_MENU);
12221227
} else {
1223-
gr_get_string_size(&w, nullptr, The_mission.name);
1224-
gr_string(Title_coords[gr_screen.res][0] - w, Title_coords[gr_screen.res][1], The_mission.name, GR_RESIZE_MENU);
1228+
gr_string(Title_coords[gr_screen.res][0] - w, Title_coords[gr_screen.res][1], buf, GR_RESIZE_MENU);
12251229
}
12261230

12271231
// maybe do objectives

code/missionui/missiondebrief.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2277,7 +2277,8 @@ void debrief_do_frame(float frametime)
22772277
{
22782278
int k=0, new_k=0;
22792279
const char *please_wait_str = XSTR("Please Wait", 1242);
2280-
char buf[256];
2280+
const size_t max_buf_len = 255;
2281+
char buf[max_buf_len+1];
22812282

22822283
Assert(Debrief_inited);
22832284

@@ -2458,8 +2459,9 @@ void debrief_do_frame(float frametime)
24582459

24592460
// draw the title of the mission
24602461
gr_set_color_fast(&Color_bright_white);
2461-
strcpy_s(buf, The_mission.name);
2462-
font::force_fit_string(buf, 255, Debrief_title_coords[gr_screen.res][2]);
2462+
strncpy(buf, The_mission.name.c_str(), max_buf_len);
2463+
buf[max_buf_len] = '\0';
2464+
font::force_fit_string(buf, max_buf_len, Debrief_title_coords[gr_screen.res][2]);
24632465
gr_string(Debrief_title_coords[gr_screen.res][0], Debrief_title_coords[gr_screen.res][1], buf, GR_RESIZE_MENU);
24642466

24652467
#if !defined(NDEBUG)

code/network/multi_dogfight.cpp

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,8 @@ void multi_df_debrief_init(bool API_Access)
245245
void multi_df_debrief_do(bool API_Access)
246246
{
247247
int k, new_k;
248-
char buf[256];
248+
const size_t max_buf_len = 255;
249+
char buf[max_buf_len+1];
249250

250251
k = chatbox_process();
251252
if (!API_Access) {
@@ -285,8 +286,9 @@ void multi_df_debrief_do(bool API_Access)
285286
chatbox_render();
286287

287288
// draw the mission title
288-
strcpy_s(buf, The_mission.name);
289-
font::force_fit_string(buf, 255, Kill_matrix_title_coords[gr_screen.res][2]);
289+
strncpy(buf, The_mission.name.c_str(), max_buf_len);
290+
buf[max_buf_len] = '\0';
291+
font::force_fit_string(buf, max_buf_len, Kill_matrix_title_coords[gr_screen.res][2]);
290292
gr_set_color_fast(&Color_bright_white);
291293
gr_string(Kill_matrix_title_coords[gr_screen.res][0],
292294
Kill_matrix_title_coords[gr_screen.res][1],
@@ -392,7 +394,7 @@ void multi_df_setup_kill_matrix()
392394
// blit the kill matrix
393395
void multi_df_blit_kill_matrix()
394396
{
395-
int idx, s_idx, str_len;
397+
int idx, s_idx;
396398
int cx, cy;
397399
char squashed_string[CALLSIGN_LEN+1] = "";
398400
int dy = gr_get_font_height() + 1;
@@ -415,15 +417,14 @@ void multi_df_blit_kill_matrix()
415417
for(idx=0; idx<Multi_df_score_count; idx++){
416418
// force the string to fit nicely
417419
strcpy_s(squashed_string, Multi_df_score[idx].callsign);
418-
font::force_fit_string(squashed_string, CALLSIGN_LEN, (int)max_text_width);
419-
gr_get_string_size(&str_len, NULL, squashed_string);
420+
int w = font::force_fit_string(squashed_string, CALLSIGN_LEN, (int)max_text_width);
420421

421422
// set color and blit the string
422423
Assert(Multi_df_score[idx].np_index >= 0);
423424
if(Multi_df_score[idx].np_index >= 0){
424425
gr_set_color_fast(Color_netplayer[Multi_df_score[idx].np_index]);
425426
}
426-
gr_string(cx + (int)((max_item_width - (float)str_len)/2.0f), cy, squashed_string, GR_RESIZE_MENU);
427+
gr_string(cx + (int)((max_item_width - (float)w)/2.0f), cy, squashed_string, GR_RESIZE_MENU);
427428

428429
// next spot
429430
cx += (int)max_item_width;
@@ -446,7 +447,6 @@ void multi_df_blit_kill_matrix()
446447
cx = Multi_df_display_coords[gr_screen.res][0];
447448
strcpy_s(squashed_string, Multi_df_score[idx].callsign);
448449
font::force_fit_string(squashed_string, CALLSIGN_LEN, (int)max_text_width);
449-
gr_get_string_size(&str_len, NULL, squashed_string);
450450
Assert(Multi_df_score[idx].np_index >= 0);
451451
if(Multi_df_score[idx].np_index >= 0){
452452
gr_set_color_fast(Color_netplayer[Multi_df_score[idx].np_index]);
@@ -469,9 +469,8 @@ void multi_df_blit_kill_matrix()
469469
}
470470

471471
// draw the string
472-
font::force_fit_string(squashed_string, CALLSIGN_LEN, (int)max_text_width);
473-
gr_get_string_size(&str_len, NULL, squashed_string);
474-
gr_string(cx + (int)((max_item_width - (float)str_len)/2.0f), cy, squashed_string, GR_RESIZE_MENU);
472+
int w = font::force_fit_string(squashed_string, CALLSIGN_LEN, (int)max_text_width);
473+
gr_string(cx + (int)((max_item_width - (float)w)/2.0f), cy, squashed_string, GR_RESIZE_MENU);
475474

476475
// next spot
477476
cx += (int)max_item_width;
@@ -480,8 +479,9 @@ void multi_df_blit_kill_matrix()
480479
// draw the row total
481480
gr_set_color_fast(Color_netplayer[Multi_df_score[idx].np_index]);
482481
sprintf(squashed_string, "(%d)", row_total);
483-
gr_get_string_size(&str_len, NULL, squashed_string);
484-
gr_string(Multi_df_display_coords[gr_screen.res][0] + Multi_df_display_coords[gr_screen.res][2] - (MULTI_DF_TOTAL_ADJUST + str_len), cy, squashed_string, GR_RESIZE_MENU);
482+
int w;
483+
gr_get_string_size(&w, nullptr, squashed_string);
484+
gr_string(Multi_df_display_coords[gr_screen.res][0] + Multi_df_display_coords[gr_screen.res][2] - (MULTI_DF_TOTAL_ADJUST + w), cy, squashed_string, GR_RESIZE_MENU);
485485

486486
cy += dy;
487487
}

code/network/multi_pxo.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3029,8 +3029,6 @@ void multi_pxo_chat_process_incoming(const char *txt,int mode)
30293029
*/
30303030
void multi_pxo_chat_blit()
30313031
{
3032-
int token_width;
3033-
30343032
// blit the title line
30353033
char title[MAX_PXO_TEXT_LEN];
30363034
memset(title,0,MAX_PXO_TEXT_LEN);
@@ -3043,10 +3041,9 @@ void multi_pxo_chat_blit()
30433041
} else {
30443042
strcpy_s(title,XSTR("Parallax Online - No Channel", 956));
30453043
}
3046-
font::force_fit_string(title, MAX_PXO_TEXT_LEN-1, Multi_pxo_chat_coords[gr_screen.res][2] - 10);
3047-
gr_get_string_size(&token_width,nullptr,title);
3044+
int title_width = font::force_fit_string(title, MAX_PXO_TEXT_LEN-1, Multi_pxo_chat_coords[gr_screen.res][2] - 10);
30483045
gr_set_color_fast(&Color_normal);
3049-
gr_string(Multi_pxo_chat_coords[gr_screen.res][0] + ((Multi_pxo_chat_coords[gr_screen.res][2] - token_width)/2), Multi_pxo_chat_title_y[gr_screen.res], title, GR_RESIZE_MENU);
3046+
gr_string(Multi_pxo_chat_coords[gr_screen.res][0] + ((Multi_pxo_chat_coords[gr_screen.res][2] - title_width)/2), Multi_pxo_chat_title_y[gr_screen.res], title, GR_RESIZE_MENU);
30503047

30513048
int disp_count, y_start;
30523049
int line_height = gr_get_font_height() + 1;
@@ -3078,12 +3075,13 @@ void multi_pxo_chat_blit()
30783075

30793076
// normal mode, just highlight the server
30803077
case CHAT_MODE_PRIVATE:
3081-
case CHAT_MODE_NORMAL:
3078+
case CHAT_MODE_NORMAL: {
30823079
char piece[MAX_CHAT_LINE_LEN + 1];
30833080
strcpy_s(piece, line->text);
30843081
tok = strtok(piece, " ");
30853082
if (tok != nullptr) {
30863083
// get the width of just the first "piece"
3084+
int token_width;
30873085
gr_get_string_size(&token_width, nullptr, tok);
30883086

30893087
// draw it brightly
@@ -3101,6 +3099,7 @@ void multi_pxo_chat_blit()
31013099
}
31023100
}
31033101
break;
3102+
}
31043103

31053104
// carry mode, display with no highlight
31063105
case CHAT_MODE_CARRY:

0 commit comments

Comments
 (0)