void dc_init(void) { if (debug_inited) { return; } debug_inited = TRUE; // Init window settings dc_font = FONT1; row_height = ((Current_font->h) * 3) / 2; // Row/Line height, in pixels col_width = Current_font->w; // Col/Character width, in pixels dc_scroll_x = 0; dc_scroll_y = 0; DCOLS = (gr_screen.max_w / col_width) - 1; // Subtract as needed. Windowed mode has some quirks with the resolution DROWS = (gr_screen.max_h / row_height) - 2; DBCOLS = DCOLS; DBROWS = 2 * DROWS; // Init History dc_history.clear(); dc_history.push_back(""); last_oldcommand = dc_history.begin(); // Init buffers dc_buffer.clear(); dc_buffer.push_back(""); dc_command_buf.reserve(MAX_CLI_LEN); dc_command_buf.clear(); sprintf(dc_title, "FreeSpace Open v%i.%i.%i", FS_VERSION_MAJOR, FS_VERSION_MINOR, FS_VERSION_BUILD); dc_printf("Debug console started.\n" ); }
ParticleEffectIndex parseEffectElement(EffectType forcedType, const SCP_string& name) { if (!optional_string("$New Effect")) { SCP_string newName; stuff_string(newName, F_NAME); auto index = ParticleManager::get()->getEffectByName(newName); if (index < 0) { error_display(0, "Unknown particle effect name '%s' encountered!", newName.c_str()); } if (forcedType != EffectType::Invalid) { // Validate the effect type auto effect = ParticleManager::get()->getEffect(index); if (effect->getType() != forcedType) { error_display(0, "Particle effect '%s' has the wrong effect type! Expected %s but was %s!", getEffectTypeName(forcedType), getEffectTypeName(effect->getType())); } } return index; } if (forcedType == EffectType::Invalid) { forcedType = parseEffectType(); } auto effect = constructEffect(name, forcedType); return ParticleManager::get()->addEffect(effect); }
bool RocketRenderingInterface::LoadTexture(TextureHandle& texture_handle, Vector2i& texture_dimensions, const String& source) { GR_DEBUG_SCOPE("libRocket::LoadTexture"); SCP_string filename; int dir_type; if (!RocketFileInterface::getCFilePath(source, filename, dir_type)) { return false; } auto period_pos = filename.rfind('.'); if (period_pos != SCP_string::npos) { filename = filename.substr(0, period_pos); } auto id = bm_load_either(filename.c_str(), nullptr, nullptr, nullptr, false, dir_type); if (id < 0) { return false; } int w, h; bm_get_info(id, &w, &h); texture_dimensions.x = w; texture_dimensions.y = h; auto* tex = new Texture(); tex->handle = id; texture_handle = get_texture_handle(tex); return true; }
// debug console function called to determine which player to kick void multi_dcf_kick() { int player_num,idx; SCP_string arg; // get the callsign of the player to kick dc_stuff_string(arg); player_num = -1; for(idx=0;idx<MAX_PLAYERS;idx++){ if(MULTI_CONNECTED(Net_players[idx]) && (stricmp(Net_players[idx].m_player->callsign, arg.c_str()) == 0)) { player_num = idx; break; } } // if we didn't find the player, notify of the results if(player_num == -1){ dc_printf("Could not find player %s to kick!", arg.c_str()); } // if we found the guy, then try and kick him else { multi_kick_player(player_num); } }
// given a valid XSTR() tag piece of text, extract the string portion, return it in out, nonzero on success int lcl_ext_get_text(const SCP_string &xstr, SCP_string &out) { size_t open_quote_pos, close_quote_pos; // this is some crazy wack-ass code. // look for the open quote open_quote_pos = xstr.find('\"'); if (open_quote_pos == SCP_string::npos) { error_display(0, "Error parsing XSTR() tag %s\n", xstr.c_str()); return 0; } // look for the close quote close_quote_pos = xstr.find('\"', open_quote_pos+1); if (close_quote_pos == SCP_string::npos) { error_display(0, "Error parsing XSTR() tag %s\n", xstr.c_str()); return 0; } // now that we know the boundaries of the actual string in the XSTR() tag, copy it out.assign(xstr, open_quote_pos + 1, close_quote_pos - open_quote_pos - 1); // success return 1; }
// ============================== IMPLEMENTATIONS ============================= void dc_do_command(SCP_string *cmd_str) { /** * Grab the first word from the cmd_str * If it is not a literal, ignore it "Invalid keyword: %s" * Search for the command... * Compare the word against valid commands * If command not found, ignore it "Invalid or unknown command: %s"\ * Process the command... * Call the function to process the command (the rest of the command line is in the parser) * Function takes care of long_help and status depending on the mode. */ int i; SCP_string command; extern debug_command* dc_commands[]; // z64: I don't like this extern here, at all. Nope nope nope. if (cmd_str->empty()) { return; } dc_parse_init(*cmd_str); dc_stuff_string_white(command); // Grab the first token, presumably this is a command for (i = 0; i < dc_commands_size; ++i) { if (stricmp(dc_commands[i]->name, command.c_str()) == 0) { break; } // Else, continue } if (i == dc_commands_size) { dc_printf("Command not found: '%s'\n", command.c_str()); return; } // Else, we found our command try { dc_commands[i]->func(); // Run the command! } catch (errParseString err) { dc_printf("Require string(s) not found: \n"); for (uint j = 0; j < err.expected_tokens.size(); ++j) { dc_printf("%i: %s\n", j, err.expected_tokens[j].c_str()); } dc_printf("Found '%s' instead\n", err.found_token.c_str()); } catch (errParse err) { dc_printf("Invalid argument. Expected %s, found '%s'\n", token_str[err.expected_type], err.found_token.c_str()); } // dc_maybe_stuff_string is vulnerable to overflow. Once the errParseOverflow throw class (or w/e) gets // implemented, this last command should be put into its own try{} catch{} block. if (dc_maybe_stuff_string(command)) { dc_printf( "Ignoring the unused command line tail '%s'\n", command.c_str() ); } }
void Warning(const char* filename, int line, const char* format, ...) { #ifndef NDEBUG SCP_string msg; va_list args; va_start(args, format); vsprintf(msg, format, args); va_end(args); ReleaseWarning(filename, line, "%s", msg.c_str()); #endif }
int parseAnimation(bool critical) { SCP_string name; stuff_string(name, F_FILESPEC); auto handle = bm_load_animation(name.c_str()); if (handle < 0) { int level = critical ? 1 : 0; error_display(level, "Failed to load effect %s!", name.c_str()); } return handle; }
void dc_printf(const char *format, ...) { SCP_string tmp; va_list args; SCP_string::iterator tmp_it; va_start(args, format); vsprintf(tmp, format, args); va_end(args); for (tmp_it = tmp.begin(); tmp_it != tmp.end(); ++tmp_it) { dc_putc(*tmp_it); } }
HKEY get_registry_keyname(char* out_keyname, const char* section) { // Every compiler from Visual Studio 2008 onward should have support for UAC #if _MSC_VER >= 1400 if (userSIDValid) { if (needsWOW64()) { if (section) { sprintf(out_keyname, "%s_Classes\\VirtualStore\\Machine\\Software\\Wow6432Node\\%s\\%s\\%s", userSID.c_str(), szCompanyName, szAppName, section); } else { sprintf(out_keyname, "%s_Classes\\VirtualStore\\Machine\\Software\\Wow6432Node\\%s\\%s", userSID.c_str(), szCompanyName, szAppName); } } else { if (section) { sprintf(out_keyname, "%s_Classes\\VirtualStore\\Machine\\Software\\%s\\%s\\%s", userSID.c_str(), szCompanyName, szAppName, section); } else { sprintf(out_keyname, "%s_Classes\\VirtualStore\\Machine\\Software\\%s\\%s", userSID.c_str(), szCompanyName, szAppName); } } return HKEY_USERS; } else { // This will probably fail if (section) { sprintf(out_keyname, "Software\\%s\\%s\\%s", szCompanyName, szAppName, section); } else { sprintf(out_keyname, "Software\\%s\\%s", szCompanyName, szAppName); } return HKEY_LOCAL_MACHINE; } #else if (section) { sprintf(out_keyname, "Software\\%s\\%s\\%s", szCompanyName, szAppName, section); } else { sprintf(out_keyname, "Software\\%s\\%s", szCompanyName, szAppName); } return HKEY_LOCAL_MACHINE; #endif }
void outwnd_printf(const char *id, const char *format, ...) { SCP_string temp; va_list args; if ( (id == NULL) || (format == NULL) ) return; va_start(args, format); vsprintf(temp, format, args); va_end(args); outwnd_print(id, temp.c_str()); }
void outwnd_printf2(const char *format, ...) { SCP_string temp; va_list args; if (format == NULL) return; va_start(args, format); vsprintf(temp, format, args); va_end(args); outwnd_print("General", temp.c_str()); }
static void opengl_purge_shader_cache_type(const char* ext) { SCP_string filter("*."); filter += ext; // Previously the cache files were stored in the mod directory. Since we have a better system now, those files // should be cleaned out. This is only needed if we have a mod directory since otherwise we would delete the actual // cache files if (Cmdline_mod != nullptr && strlen(Cmdline_mod) > 0) { SCP_vector<SCP_string> cache_files; cf_get_file_list(cache_files, CF_TYPE_CACHE, filter.c_str(), CF_SORT_NONE, nullptr, CF_LOCATION_TYPE_PRIMARY_MOD | CF_LOCATION_TYPE_SECONDARY_MODS); for (auto& file : cache_files) { cf_delete((file + "." + ext).c_str(), CF_TYPE_CACHE, CF_LOCATION_TYPE_PRIMARY_MOD | CF_LOCATION_TYPE_SECONDARY_MODS); } } SCP_vector<SCP_string> cache_files; SCP_vector<file_list_info> file_info; cf_get_file_list(cache_files, CF_TYPE_CACHE, filter.c_str(), CF_SORT_NONE, &file_info, CF_LOCATION_ROOT_USER | CF_LOCATION_ROOT_GAME | CF_LOCATION_TYPE_ROOT); Assertion(cache_files.size() == file_info.size(), "cf_get_file_list returned different sizes for file names and file informations!"); const auto TIMEOUT = 2.0 * 30.0 * 24.0 * 60.0 * 60.0; // purge timeout in seconds which is ~2 months const SCP_string PREFIX = "ogl_shader-"; auto now = std::time(nullptr); for (size_t i = 0; i < cache_files.size(); ++i) { auto& name = cache_files[i]; auto write_time = file_info[i].write_time; if (name.compare(0, PREFIX.size(), PREFIX) != 0) { // Not an OpenGL cache file continue; } auto diff = std::difftime(now, write_time); if (diff > TIMEOUT) { auto full_name = name + "." + ext; cf_delete(full_name.c_str(), CF_TYPE_CACHE); } } }
void WarningEx(const char* filename, int line, const char* format, ...) { #ifndef NDEBUG if (Cmdline_extra_warn) { SCP_string msg; va_list args; va_start(args, format); vsprintf(msg, format, args); va_end(args); Warning(filename, line, "%s", msg.c_str()); } #endif }
/* * validate that a pilot/player was created with the same language FSO is currently using * * @param pilots callsign * @note not longer needed if intel entry "primary keys" change to a non-translated value */ bool valid_pilot_lang(char *callsign) { char pilot_lang[LCL_LANG_NAME_LEN+1], current_lang[LCL_LANG_NAME_LEN+1]; SCP_string filename = callsign; filename += ".plr"; lcl_get_language_name(current_lang); if (Pilot.verify(filename.c_str(), NULL, pilot_lang)) { if (!strcmp(current_lang, pilot_lang)) { return true; } } return false; }
/** * Builds the output text. */ void profile_dump_output() { if (Cmdline_frame_profile) { end_profile_time = timer_get_microseconds(); if (Cmdline_profile_write_file) { profiling_file << end_profile_time << ";" << (end_profile_time - start_profile_time) << std::endl; } profile_output.clear(); profile_output += " Avg : Min : Max : # : Profile Name\n"; profile_output += "----------------------------------------\n"; for(int i = 0; i < (int)samples.size(); i++) { uint64_t sample_time; float percent_time, avg_time, min_time, max_time; uint64_t avg_micro_seconds, min_micro_seconds, max_micro_seconds; Assert(samples[i].open_profiles == 0); sample_time = samples[i].accumulator - samples[i].children_sample_time; if (end_profile_time == start_profile_time) { percent_time = 0.0f; } else { percent_time = (i2fl(sample_time) / i2fl(end_profile_time - start_profile_time)) *100.0f; } avg_micro_seconds = min_micro_seconds = max_micro_seconds = sample_time; avg_time = min_time = max_time = percent_time; // add new measurement into the history and get avg, min, and max store_profile_in_history(samples[i].name, percent_time, sample_time); get_profile_from_history(samples[i].name, &avg_time, &min_time, &max_time, &avg_micro_seconds, &min_micro_seconds, &max_micro_seconds); // format the data char avg[64], min[64], max[64], num[64]; sprintf(avg, "%3.1f%% (%3.1fms)", avg_time, i2fl(avg_micro_seconds)*0.001f); sprintf(min, "%3.1f%% (%3.1fms)", min_time, i2fl(min_micro_seconds)*0.001f); sprintf(max, "%3.1f%% (%3.1fms)", max_time, i2fl(max_micro_seconds)*0.001f); sprintf(num, "%3d", samples[i].profile_instances); SCP_string indented_name(samples[i].name); for(uint indent = 0; indent < samples[i].num_parents; indent++) { indented_name = ">" + indented_name; } char line[256]; sprintf(line, "%5s : %5s : %5s : %3s : ", avg, min, max, num); profile_output += line + indented_name + "\n"; } samples.clear(); start_profile_time = timer_get_microseconds(); } }
void dc_draw(bool show_prompt = FALSE) { gr_clear(); font::set_font(dc_font); gr_set_color_fast( &Color_bright ); int w; gr_get_string_size(&w, nullptr, dc_title.c_str()); gr_string((gr_screen.clip_width - w) / 2, 3, dc_title.c_str(), GR_RESIZE_NONE ); gr_set_color_fast( &Color_normal ); dc_draw_window(show_prompt); gr_flip(); }
// printf function itself called by the ml_printf macro void ml_printf(const char *format, ...) { SCP_string temp; va_list args; if (format == NULL) { return; } // format the text va_start(args, format); vsprintf(temp, format, args); va_end(args); // log the string including the time log_string(LOGFILE_MULTI_LOG, temp.c_str(), 1); }
ParticleEffectIndex ParticleManager::getEffectByName(const SCP_string& name) { if (name.empty()) { // Don't allow empty names, it's a special case for effects that should not be referenced. return -1; } auto foundIterator = find_if(m_effects.begin(), m_effects.end(), [&name](const std::shared_ptr<ParticleEffect>& ptr) { return !stricmp(ptr->getName().c_str(), name.c_str()); }); if (foundIterator == m_effects.end()) { return -1; } return distance(m_effects.begin(), foundIterator); }
ParticleEffectIndex parseEffect(const SCP_string& objectName) { SCP_string name; stuff_string(name, F_NAME); auto idx = ParticleManager::get()->getEffectByName(name); if (idx < 0) { if (objectName.empty()) { error_display(0, "Unknown particle effect name '%s' encountered!", name.c_str()); } else { error_display(0, "Unknown particle effect name '%s' encountered while parsing '%s'!", name.c_str(), objectName.c_str()); } } return idx; }
void AssertMessage(const char * text, const char * filename, int linenum, const char * format, ...) { // We only want to display the file name filename = clean_filename(filename); SCP_stringstream msgStream; msgStream << "Assert: \"" << text << "\"\n"; msgStream << "File: " << filename << "\n"; msgStream << "Line: " << linenum << "\n"; if (format != nullptr) { SCP_string buffer; va_list args; va_start(args, format); vsprintf(buffer, format, args); va_end(args); msgStream << buffer << "\n"; mprintf(("ASSERTION: \"%s\" at %s:%d\n %s\n", text, filename, linenum, buffer.c_str())); } else { // No additional message mprintf(("ASSERTION: \"%s\" at %s:%d\n", text, filename, linenum)); } if (running_unittests) { throw AssertException(msgStream.str()); } msgStream << "\n"; msgStream << dump_stacktrace(); SCP_string messageText = msgStream.str(); set_clipboard_text(messageText.c_str()); messageText = truncateLines(msgStream, Messagebox_lines); messageText += "\n[ This info is in the clipboard so you can paste it somewhere now ]\n"; messageText += "\n\nUse Debug to break into Debugger, Exit will close the application.\n"; Error(messageText.c_str()); }
void gamesnd_parse_entry(game_snd *gs, bool no_create, SCP_vector<game_snd> *lookupVector) { SCP_string name; stuff_string(name, F_NAME, "\t \n"); if (!no_create) { if (lookupVector != NULL) { if (gamesnd_lookup_name(name.c_str(), *lookupVector) >= 0) { Warning(LOCATION, "Duplicate sound name \"%s\" found!", name.c_str()); } } gs->name = name; } else { int vectorIndex = gamesnd_lookup_name(name.c_str(), *lookupVector); if (vectorIndex < 0) { Warning(LOCATION, "No existing sound entry with name \"%s\" found!", name.c_str()); no_create = false; gs->name = name; } else { gs = &lookupVector->at(vectorIndex); } } if (optional_string("+Filename:")) { parse_gamesnd_new(gs, no_create); } else { parse_gamesnd_old(gs); } }
GLint opengl::ShaderUniforms::findUniformLocation(const SCP_string& name) { auto iter = _uniform_locations.find(name); if (iter == _uniform_locations.end()) { // Lazily initialize the uniform locations when required. This avoids keeping a list of all uniforms in the code auto location = glGetUniformLocation(_program->getShaderHandle(), name.c_str()); if (location == -1) { // This can happen if the uniform has been optimized out by the driver mprintf(("WARNING: Failed to find uniform '%s'.\n", name.c_str())); } _uniform_locations.insert(std::make_pair(name, location)); return location; } else { return iter->second; } }
void opengl::ShaderUniforms::setUniformMatrix4fv(const SCP_string &name, const int count, const matrix4 *val) { Assertion(GL_state.IsCurrentProgram(_program->getShaderHandle()), "The program must be current before setting uniforms!"); size_t uniform_index = findUniform(name); bool resident = false; if (uniform_index != (size_t)-1) { Assert((size_t)uniform_index < _uniforms.size()); uniform_bind *bind_info = &_uniforms[uniform_index]; if (bind_info->type == uniform_bind::MATRIX4 && bind_info->count == count) { bool equal = true; // if the values are close enough, pass. for (int i = 0; i < count; ++i) { if (!vm_matrix_equal(val[i], _uniform_data_matrix4[bind_info->index + i])) { equal = false; break; } } if (equal) { return; } resident = true; for (int i = 0; i < count; ++i) { _uniform_data_matrix4[bind_info->index + i] = val[i]; } } } if (!resident) { // uniform doesn't exist in our previous uniform block so queue this new value for (int i = 0; i < count; ++i) { _uniform_data_matrix4.push_back(val[i]); } uniform_bind new_bind; new_bind.count = count; new_bind.index = _uniform_data_matrix4.size() - count; // new_bind.index = num_matrix_uniforms - count; new_bind.type = uniform_bind::MATRIX4; new_bind.name = name; _uniforms.push_back(new_bind); _uniform_lookup[name] = _uniforms.size() - 1; } glUniformMatrix4fv(findUniformLocation(name.c_str()), count, GL_FALSE, (const GLfloat*)val); }
/** * Parse the sounds.tbl file, and load the specified sounds. */ void gamesnd_parse_soundstbl() { parse_sound_table("sounds.tbl"); parse_modular_table("*-snd.tbm", parse_sound_table); // if we are missing any species then report if (!missingFlybySounds.empty()) { SCP_string errorString; for (size_t i = 0; i < missingFlybySounds.size(); i++) { errorString.append(missingFlybySounds[i].species_name); errorString.append("\n"); } Error(LOCATION, "The following species are missing flyby sounds in sounds.tbl:\n%s", errorString.c_str()); } missingFlybySounds.clear(); }
int parse_font() { int font_idx; SCP_string input; stuff_string(input, F_NAME); SCP_stringstream ss(input); int fontNum; ss >> fontNum; if (ss.fail()) { fontNum = FontManager::getFontIndex(input); if (fontNum < 0) { error_display(0, "Invalid font name \"%s\"!", input.c_str()); font_idx = -1; } else { font_idx = fontNum; } } else { if (fontNum < 0 || fontNum >= FontManager::numberOfFonts()) { error_display(0, "Invalid font number %d! must be greater or equal to zero and smaller than %d.", fontNum, FontManager::numberOfFonts()); font_idx = -1; } else { font_idx = fontNum; } } return font_idx; }
void opengl_uniform_state::setUniformMatrix4fv(const SCP_string &name, const int count, const matrix4 *val) { size_t uniform_index = findUniform(name); bool resident = false; if ( uniform_index != (size_t)-1) { Assert( (size_t)uniform_index < uniforms.size() ); uniform_bind *bind_info = &uniforms[uniform_index]; if ( bind_info->type == uniform_bind::MATRIX4 && bind_info->count == count ) { bool equal = true; // if the values are close enough, pass. for ( int i = 0; i < count; ++i ) { if ( !vm_matrix_equal(val[i], uniform_data_matrix4[bind_info->index+i]) ) { equal = false; break; } } if ( equal ) { return; } resident = true; for ( int i = 0; i < count; ++i ) { uniform_data_matrix4[bind_info->index+i] = val[i]; } } } if ( !resident ) { // uniform doesn't exist in our previous uniform block so queue this new value for ( int i = 0; i < count; ++i ) { uniform_data_matrix4.push_back(val[i]); } uniform_bind new_bind; new_bind.count = count; new_bind.index = uniform_data_matrix4.size() - count; // new_bind.index = num_matrix_uniforms - count; new_bind.type = uniform_bind::MATRIX4; new_bind.name = name; uniforms.push_back(new_bind); uniform_lookup[name] = uniforms.size()-1; } glUniformMatrix4fv(opengl_shader_get_uniform(name.c_str()), count, GL_FALSE, (const GLfloat*)val); }
// printf function itself called by the ml_printf macro void log_printf(int logfile_type, char *format, ...) { SCP_string temp; va_list args; if (format == NULL) { return; } // if we don't have a valid logfile do nothing if (logfiles[logfile_type].log_file == NULL) { return; } // format the text va_start(args, format); vsprintf(temp, format, args); va_end(args); // log the string log_string(logfile_type, temp.c_str()); }
void dc_draw(bool show_prompt = FALSE) { gr_clear(); gr_set_font(dc_font); gr_set_color_fast( &Color_bright ); gr_string( 0x8000, 3, dc_title.c_str(), GR_RESIZE_NONE ); gr_set_color_fast( &Color_normal ); dc_draw_window(show_prompt); gr_flip(); }
/** * Load a shader file from disc or from the builtin defaults in def_files.cpp if none can be found. * This function will also create a list of preprocessor defines for the GLSL compiler based on the shader flags * and the supported GLSL version as reported by the GPU driver. * * @param shader shader_type enum defined with which shader we're loading * @param filename C-string holding the filename (with extension) of the shader file * @param flags integer variable holding a combination of SDR_* flags * @return C-string holding the complete shader source code */ static SCP_string opengl_load_shader(const char* filename) { SCP_string content; if (Enable_external_shaders) { CFILE* cf_shader = cfopen(filename, "rt", CFILE_NORMAL, CF_TYPE_EFFECTS); if (cf_shader != NULL) { int len = cfilelength(cf_shader); content.resize(len); cfread(&content[0], len + 1, 1, cf_shader); cfclose(cf_shader); return content; } } //If we're still here, proceed with internals mprintf((" Loading built-in default shader for: %s\n", filename)); auto def_shader = defaults_get_file(filename); content.assign(reinterpret_cast<const char*>(def_shader.data), def_shader.size); return content; }