bool fs2netd_get_valid_missions() { int rc = 0; if ( !Logged_in ) { return false; } FS2NetD_file_list.clear(); do_full_packet = true; In_process = true; if (Is_standalone) { do { rc = fs2netd_get_valid_missions_do(); } while (!rc); } else { rc = popup_till_condition(fs2netd_get_valid_missions_do, XSTR("&Cancel", 779), XSTR("Starting mission validation", 1588)); } In_process = false; Local_timeout = -1; FS2NetD_file_list.clear(); //-V586 switch (rc) { // canceled by popup case 0: return false; // timed out case 1: if ( !Is_standalone ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Mission validation timed out!", 1589)); } return false; // no missions case 2: if ( !Is_standalone ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("No missions are available from the server for validation!", 1590)); } return false; // out of memory case 3: if ( !Is_standalone ) { popup(PF_USE_AFFIRMATIVE_ICON, 1, POPUP_OK, XSTR("Memory error during mission validation!", 1591)); } return false; } return true; }
void fs2netd_close() { // make sure that a hosted games is de-listed fs2netd_gameserver_disconnect(); FS2NetD_Disconnect(); fs2netd_reset_state(); PXO_options_loaded = false; Table_valid_status.clear(); FS2NetD_file_list.clear(); FS2NetD_ban_list.clear(); }
// Reset everything between levels void particle_init() { int fps; Particles_enabled = (Detail.num_particles > 0); Num_particles = 0; Particles.clear(); // FIRE!!! if ( Anim_bitmap_id_fire == -1 ) { Anim_bitmap_id_fire = bm_load_animation( "particleexp01", &Anim_num_frames_fire, &fps, NULL, 0 ); } // Cough, cough if ( Anim_bitmap_id_smoke == -1 ) { Anim_bitmap_id_smoke = bm_load_animation( "particlesmoke01", &Anim_num_frames_smoke, &fps, NULL, 0 ); } // wheeze if ( Anim_bitmap_id_smoke2 == -1 ) { Anim_bitmap_id_smoke2 = bm_load_animation( "particlesmoke02", &Anim_num_frames_smoke2, &fps, NULL, 0 ); } // grab a vertex buffer object if ( Particle_buffer_object < 0 ) { Particle_buffer_object = gr_create_stream_buffer(); } }
/** * Initializes the shader system. Creates a 1x1 texture that can be used as a fallback texture when framebuffer support is missing. * Also compiles the shaders used for particle rendering. */ void opengl_shader_init() { glGenTextures(1,&Framebuffer_fallback_texture_id); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Framebuffer_fallback_texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); GLuint pixels[4] = {0,0,0,0}; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &pixels); GL_shader.clear(); // Reserve 32 shader slots. This should cover most use cases in real life. GL_shader.reserve(32); // compile effect shaders gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_PARTICLE, 0); gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_PARTICLE, SDR_FLAG_PARTICLE_POINT_GEN); gr_opengl_maybe_create_shader(SDR_TYPE_EFFECT_DISTORTION, 0); gr_opengl_maybe_create_shader(SDR_TYPE_SHIELD_DECAL, 0); // compile deferred lighting shaders opengl_shader_compile_deferred_light_shader(); // compile passthrough shader opengl_shader_compile_passthrough_shader(); mprintf(("\n")); }
void snd_clear() { Sounds.clear(); // reset how much storage sounds are taking up in memory Snd_sram = 0; }
/** * Initializes the shader system. Creates a 1x1 texture that can be used as a fallback texture when framebuffer support is missing. * Also compiles the shaders used for particle rendering. */ void opengl_shader_init() { if ( !Use_GLSL ) { return; } glGenTextures(1,&Framebuffer_fallback_texture_id); GL_state.Texture.SetActiveUnit(0); GL_state.Texture.SetTarget(GL_TEXTURE_2D); GL_state.Texture.Enable(Framebuffer_fallback_texture_id); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); GLuint pixels[4] = {0,0,0,0}; glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 1, 1, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, &pixels); if (Cmdline_no_glsl_model_rendering) { Use_GLSL = 1; } GL_shader.clear(); // Reserve 32 shader slots. This should cover most use cases in real life. GL_shader.reserve(32); // Compile the particle shaders, since these are most definitely going to be used opengl_compile_main_shader(SDR_FLAG_SOFT_QUAD); opengl_compile_main_shader(SDR_FLAG_SOFT_QUAD | SDR_FLAG_DISTORTION); mprintf(("\n")); }
void opengl_post_process_shutdown() { if ( !Post_initialized ) { return; } if (Post_framebuffer_id[0]) { glDeleteFramebuffers(1, &Post_framebuffer_id[0]); Post_framebuffer_id[0] = 0; if (Post_framebuffer_id[1]) { glDeleteFramebuffers(1, &Post_framebuffer_id[1]); Post_framebuffer_id[1] = 0; } } Post_effects.clear(); opengl_post_process_shutdown_bloom(); Post_in_frame = false; Post_active_shader_index = 0; Post_initialized = 0; }
/** * Go through GL_shader and call glDeleteObject() for all created shaders, then clear GL_shader */ void opengl_shader_shutdown() { size_t i; if ( !is_minimum_GLSL_version() ) { return; } for (i = 0; i < GL_shader.size(); i++) { if (GL_shader[i].program_id) { vglDeleteObjectARB(GL_shader[i].program_id); GL_shader[i].program_id = 0; } GL_shader[i].uniforms.clear(); GL_shader[i].attributes.clear(); GL_shader[i].uniform_blocks.clear(); } GL_shader.clear(); if (GLshader_info_log != NULL) { vm_free(GLshader_info_log); GLshader_info_log = NULL; } }
/** * 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(); } }
// initialization stuff for cutscenes void cutscene_init() { atexit(cutscene_close); char buf[MULTITEXT_LENGTH]; int rval; cutscene_info cutinfo; if ((rval = setjmp(parse_abort)) != 0) { mprintf(("TABLES: Unable to parse '%s'! Error code = %i.\n", "cutscenes.tbl", rval)); return; } read_file_text("cutscenes.tbl", CF_TYPE_TABLES); reset_parse(); // parse in all the cutscenes Cutscenes.clear(); skip_to_string("#Cutscenes"); ignore_white_space(); bool isFirstCutscene = true; while ( required_string_either("#End", "$Filename:") ) { required_string("$Filename:"); stuff_string( cutinfo.filename, F_PATHNAME, MAX_FILENAME_LEN ); required_string("$Name:"); stuff_string( cutinfo.name, F_NAME, NAME_LENGTH ); required_string("$Description:"); stuff_string(buf, F_MULTITEXT, sizeof(buf)); drop_white_space(buf); compact_multitext_string(buf); cutinfo.description = vm_strdup(buf); if (optional_string("$cd:")) stuff_int( &cutinfo.cd ); else cutinfo.cd = 0; cutinfo.viewable = false; if (isFirstCutscene) { isFirstCutscene = false; // The original code assumes the first movie is the intro, so always viewable cutinfo.viewable = true; } if (optional_string("$Always Viewable:")) { stuff_boolean(&cutinfo.viewable); } Cutscenes.push_back(cutinfo); } required_string("#End"); }
// only call from game_shutdown()!!! void particle_close() { for (SCP_vector<particle*>::iterator p = Particles.begin(); p != Particles.end(); ++p) { (*p)->signature = 0; delete *p; } Particles.clear(); }
void cam_close() { //Set Current_camera to nothing Current_camera = camid(); for (auto ii = Cameras.begin(); ii != Cameras.end(); ++ii) { delete * ii; } Cameras.clear(); }
void obj_find_overlap_colliders(SCP_vector<int> *overlap_list_out, SCP_vector<int> *list, int axis, bool collide) { size_t i, j; bool overlapped; bool first_not_added = true; SCP_vector<int> overlappers; float min; float max; float overlap_min; float overlap_max; overlappers.clear(); for ( i = 0; i < (*list).size(); ++i ) { overlapped = false; min = obj_get_collider_endpoint((*list)[i], axis, true); max = obj_get_collider_endpoint((*list)[i], axis, false); for ( j = 0; j < overlappers.size(); ) { overlap_min = obj_get_collider_endpoint(overlappers[j], axis, true); overlap_max = obj_get_collider_endpoint(overlappers[j], axis, false); if ( min <= overlap_max ) { overlapped = true; if ( overlappers.size() == 1 && first_not_added ) { first_not_added = false; overlap_list_out->push_back(overlappers[j]); } if ( collide ) { obj_collide_pair(&Objects[(*list)[i]], &Objects[overlappers[j]]); } } else { overlappers[j] = overlappers.back(); overlappers.pop_back(); continue; } ++j; } if ( overlappers.size() == 0 ) { first_not_added = true; } if ( overlapped ) { overlap_list_out->push_back((*list)[i]); } overlappers.push_back((*list)[i]); } overlapped = true; }
void credits_close() { int i; for (i=0; i<Credits_num_images; i++) { if (Credits_bmps[i] >= 0){ bm_release(Credits_bmps[i]); } } Credits_bmps.clear(); credits_stop_music(true); Credit_text_parts.clear(); if (Background_bitmap){ bm_release(Background_bitmap); } Ui_window.destroy(); common_free_interface_palette(); // restore game palette }
// kill all active particles void particle_kill_all() { // kill all active particles Num_particles = 0; Num_particles_hwm = 0; for (SCP_vector<particle*>::iterator p = Particles.begin(); p != Particles.end(); ++p) { (*p)->signature = 0; delete *p; } Particles.clear(); }
void os_poll() { // Replay the buffered events auto end = buffered_events.end(); for (auto it = buffered_events.begin(); it != end; ++it) { handle_sdl_event(*it); } buffered_events.clear(); SDL_Event event; while (SDL_PollEvent(&event)) { handle_sdl_event(event); } }
void cutscenes_screen_init() { int i; ui_button_info *b; Ui_window.create(0, 0, gr_screen.max_w_unscaled, gr_screen.max_h_unscaled, 0); Ui_window.set_mask_bmap(Cutscene_mask_name[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, (i < 2), 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 xstrs for(i=0; i<NUM_CUTSCENE_TEXT; i++){ Ui_window.add_XSTR(&Cutscene_text[gr_screen.res][i]); } Buttons[gr_screen.res][EXIT_BUTTON].button.set_hotkey(KEY_CTRLED | KEY_ENTER); Buttons[gr_screen.res][SCROLL_UP_BUTTON].button.set_hotkey(KEY_PAGEUP); Buttons[gr_screen.res][SCROLL_DOWN_BUTTON].button.set_hotkey(KEY_PAGEDOWN); List_region.create(&Ui_window, "", Cutscene_list_coords[gr_screen.res][0], Cutscene_list_coords[gr_screen.res][1], Cutscene_list_coords[gr_screen.res][2], Cutscene_list_coords[gr_screen.res][3], 0, 1); List_region.hide(); // set up hotkeys for buttons so we draw the correct animation frame when a key is pressed Buttons[gr_screen.res][SCROLL_UP_BUTTON].button.set_hotkey(KEY_PAGEUP); Buttons[gr_screen.res][SCROLL_DOWN_BUTTON].button.set_hotkey(KEY_PAGEDOWN); Background_bitmap = bm_load(Cutscene_bitmap_name[gr_screen.res]); Scroll_offset = Selected_line = 0; Description_index = -1; Cutscene_list.clear(); int u = 0; for (SCP_vector<cutscene_info>::iterator cut = Cutscenes.begin(); cut != Cutscenes.end(); ++cut, u++) { if ( (*cut).viewable ) { Cutscene_list.push_back(u); } } }
/** * @brief Writes JSON tracing data to a file if the commandlinfe option is enabled */ void profile_dump_json_output() { if (Cmdline_json_profiling) { std::lock_guard<std::mutex> guard(json_mutex); // FIXME: This could be improved by using only a single thread and a synchronized bounded // queue. Boost has an implementation of that. tracing_frame_data frame_data; frame_data.data = current_frame_data; frame_data.frame_num = ++json_frame_num; pending_frame_data.push_back(std::move(frame_data)); current_frame_data.clear(); process_pending_data(); } }
void species_init() { if (Species_initted) return; Species_info.clear(); if (cf_exists_full("species_defs.tbl", CF_TYPE_TABLES)) parse_species_tbl("species_defs.tbl"); else parse_species_tbl(NULL); parse_modular_table("*-sdf.tbm", parse_species_tbl); Species_initted = 1; }
/** * 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(); }
void fs2netd_update_ban_list() { int rc = 0; if ( !Logged_in ) { return; } // destroy the file prior to updating cf_delete( "banlist.cfg", CF_TYPE_DATA ); do_full_packet = true; In_process = true; if (Is_standalone) { do { rc = fs2netd_update_ban_list_do(); } while (!rc); } else { rc = popup_till_condition(fs2netd_update_ban_list_do, XSTR("&Cancel", 779), XSTR("Requesting IP ban list", 1587)); } In_process = false; Local_timeout = -1; if ( !FS2NetD_ban_list.empty() ) { CFILE *banlist_cfg = cfopen("banlist.cfg", "wt", CFILE_NORMAL, CF_TYPE_DATA); if (banlist_cfg != NULL) { for (SCP_vector<SCP_string>::iterator bl = FS2NetD_ban_list.begin(); bl != FS2NetD_ban_list.end(); ++bl) { cfputs( const_cast<char*>(bl->c_str()), banlist_cfg ); } cfclose(banlist_cfg); } } FS2NetD_ban_list.clear(); }
void profile_deinit() { if (Cmdline_profile_write_file) { if (profiling_file.is_open()) { profiling_file.flush(); profiling_file.close(); } } if (Cmdline_json_profiling) { profile_dump_json_output(); while (!pending_frame_data.empty()) { process_pending_data(); } } for (auto obj : query_objects) { gr_delete_query_object(obj); } query_objects.clear(); SCP_queue<int>().swap(free_query_objects); }
/** * Go through GL_shader and call glDeleteObject() for all created shaders, then clear GL_shader */ void opengl_shader_shutdown() { size_t i; if ( !Use_GLSL ) { return; } for (i = 0; i < GL_shader.size(); i++) { if (GL_shader[i].program_id) { vglDeleteObjectARB(GL_shader[i].program_id); GL_shader[i].program_id = 0; } GL_shader[i].uniforms.clear(); } GL_shader.clear(); if (GLshader_info_log != NULL) { vm_free(GLshader_info_log); GLshader_info_log = NULL; } }
void cutscenes_screen_do_frame() { int i, k, y, z; int font_height = gr_get_font_height(); int select_tease_line = -1; k = Ui_window.process(); switch (k) { case KEY_DOWN: // select next line cutscenes_screen_scroll_line_down(); break; case KEY_UP: // select previous line cutscenes_screen_scroll_line_up(); break; case KEY_TAB: case KEY_CTRLED | KEY_DOWN: cutscenes_screen_button_pressed(CREDITS_BUTTON); break; case KEY_SHIFTED | KEY_TAB: case KEY_CTRLED | KEY_UP: cutscenes_screen_button_pressed(SIMULATOR_BUTTON); break; case KEY_ENTER: cutscenes_screen_play(); break; case KEY_ESC: // cancel gameseq_post_event(GS_EVENT_MAIN_MENU); game_flush(); break; case KEY_F1: // show help overlay break; case KEY_F2: // goto options screen gameseq_post_event(GS_EVENT_OPTIONS_MENU); break; // the "show-all" hotkey case KEY_CTRLED | KEY_SHIFTED | KEY_S: { Cutscene_list.clear(); size_t size = Cutscenes.size(); for (size_t t = 0; t < size; t++) { Cutscene_list.push_back((int)t); } break; } } // end switch for (i=0; i<NUM_BUTTONS; i++){ if (Buttons[gr_screen.res][i].button.pressed()){ if (cutscenes_screen_button_pressed(i)){ return; } } } if (List_region.button_down()) { List_region.get_mouse_pos(NULL, &y); z = Scroll_offset + y / font_height; if ((z >= 0) && (z < (int)Cutscene_list.size())) select_tease_line = z; } if (List_region.pressed()) { List_region.get_mouse_pos(NULL, &y); z = Scroll_offset + y / font_height; if ((z >= 0) && (z < (int)Cutscene_list.size())) Selected_line = z; } GR_MAYBE_CLEAR_RES(Background_bitmap); if (Background_bitmap >= 0) { gr_set_bitmap(Background_bitmap); gr_bitmap(0, 0); } Ui_window.draw(); for (i=TECH_DATABASE_BUTTON; i<=CREDITS_BUTTON; i++){ if (Buttons[gr_screen.res][i].button.button_down()){ break; } } if (i > CREDITS_BUTTON){ Buttons[gr_screen.res][CUTSCENES_BUTTON].button.draw_forced(2); } y = 0; z = Scroll_offset; while (y + font_height <= Cutscene_list_coords[gr_screen.res][3]) { if (z >= (int)Cutscene_list.size()){ break; } if (z == Selected_line){ gr_set_color_fast(&Color_text_selected); } else if (z == select_tease_line) { gr_set_color_fast(&Color_text_subselected); } else { gr_set_color_fast(&Color_text_normal); } gr_printf(Cutscene_list_coords[gr_screen.res][0], Cutscene_list_coords[gr_screen.res][1] + y, Cutscenes[Cutscene_list[z]].name); y += font_height; z++; } if (Description_index != Selected_line) { char *src = NULL; Description_index = Selected_line; Text_size = 0; if ( Description_index < (int)Cutscene_list.size( ) && (int)Cutscene_list[ Description_index ] < (int)Cutscenes.size( ) ) { src = Cutscenes[Cutscene_list[Description_index]].description; if (src) { Text_size = split_str(src, Cutscene_desc_coords[gr_screen.res][2], Text_line_size, Text_lines, Cutscene_max_text_lines[gr_screen.res]); Assert(Text_size >= 0 && Text_size < Cutscene_max_text_lines[gr_screen.res]); } } } if (Description_index >= 0) { int len; char line[MAX_TEXT_LINE_LEN + 1]; gr_set_color_fast(&Color_text_normal); y = 0; z = Text_offset; while (y + font_height <= Cutscene_desc_coords[gr_screen.res][3]) { if (z >= Text_size || z >= MAX_TEXT_LINES-1) break; len = Text_line_size[z]; if (len > MAX_TEXT_LINE_LEN) len = MAX_TEXT_LINE_LEN; strncpy(line, Text_lines[z], len); line[len] = 0; gr_string(Cutscene_desc_coords[gr_screen.res][0], Cutscene_desc_coords[gr_screen.res][1] + y, line); y += font_height; z++; } } gr_flip(); }
/** * Go through GL_shader and call glDeleteObject() for all created shaders, then clear GL_shader */ void opengl_shader_shutdown() { GL_shader.clear(); GL_shader_map.clear(); }
void credits_parse_table(const char* filename) { try { read_file_text(filename, CF_TYPE_TABLES); reset_parse(); // any metadata? if (optional_string("$Music:")) { stuff_string(Credits_music_name, F_NAME, NAME_LENGTH); } if (optional_string("$Number of Images:")) { int temp; stuff_int(&temp); if (temp > 0) Credits_num_images = temp; } if (optional_string("$Start Image Index:")) { stuff_int(&Credits_artwork_index); // bounds check if (Credits_artwork_index < 0) { Credits_artwork_index = 0; } else if (Credits_artwork_index >= Credits_num_images) { Credits_artwork_index = Credits_num_images - 1; } } if (optional_string("$Text scroll rate:")) { stuff_float(&Credits_scroll_rate); if (Credits_scroll_rate < 0.01f) Credits_scroll_rate = 0.01f; } if (optional_string("$Artworks display time:")) { stuff_float(&Credits_artwork_display_time); if (Credits_artwork_display_time < 0.01f) Credits_artwork_display_time = 0.01f; } if (optional_string("$Artworks fade time:")) { stuff_float(&Credits_artwork_fade_time); if (Credits_artwork_fade_time < 0.01f) Credits_artwork_fade_time = 0.01f; } if (optional_string("$SCP Credits position:")) { char mode[NAME_LENGTH]; stuff_string(mode, F_NAME, NAME_LENGTH); if (!stricmp(mode, "Start")) SCP_credits_position = START; else if (!stricmp(mode, "End")) SCP_credits_position = END; else Warning(LOCATION, "Unknown credits position mode \"%s\".", mode); } ignore_white_space(); SCP_string credits_text; SCP_string line; SCP_vector<int> charNum; SCP_vector<const char*> lines; int numLines = -1; bool first_run = true; while (!check_for_string_raw("#end")) { // Read in a line of text stuff_string_line(line); // This is a bit odd but it means if a total conversion uses different credits the // Volition credit won't happen // Also don't append the default credits anymore when there was already a parsed table if (first_run && !Credits_parsed && !line.compare(mod_check)) { credits_text.append(unmodified_credits); } first_run = false; if (line.empty()) { // If the line is empty then just append a newline, don't bother with splitting it first credits_text.append("\n"); } else { // split_str doesn't take care of this. charNum.clear(); // Split the string into multiple lines if it's too long numLines = split_str(line.c_str(), Credits_text_coords[gr_screen.res][2], charNum, lines, -1); // Make sure that we have valid data Assertion(lines.size() == (size_t)numLines, "split_str reported %d lines but vector contains " SIZE_T_ARG " entries!", numLines, lines.size()); Assertion(lines.size() <= charNum.size(), "Something has gone wrong while splitting strings. Got " SIZE_T_ARG " lines but only " SIZE_T_ARG " chacter lengths.", lines.size(), charNum.size()); // Now add all splitted lines to the credit text and append a newline to the end for (int i = 0; i < numLines; i++) { credits_text.append(SCP_string(lines[i], charNum[i])); credits_text.append("\n"); } } } Credit_text_parts.push_back(credits_text); Credits_parsed = true; } catch (const parse::ParseException& e) { mprintf(("TABLES: Unable to parse '%s'! Error message = %s.\n", filename, e.what())); return; } }
void obj_reset_colliders() { Collision_sort_list.clear(); Collision_cached_pairs.clear(); }
/* * Record the current state of the players wingman & ships with the "red-alert-carry" flag * Wingmen without the red-alert-carry flag are only stored if they survive * dead wingmen must still be handled in red_alert_bash_wingman_status */ void red_alert_store_wingman_status() { ship *shipp; red_alert_ship_status ras; ship_obj *so; object *ship_objp; // store the mission filename for the red alert precursor mission Red_alert_precursor_mission = Game_current_mission_filename; // Pyro3d - Clear list of stored red alert ships // Probably not the best solution, but it prevents an assertion in change_ship_type() Red_alert_wingman_status.clear(); // store status for all existing ships for ( so = GET_FIRST(&Ship_obj_list); so != END_OF_LIST(&Ship_obj_list); so = GET_NEXT(so) ) { ship_objp = &Objects[so->objnum]; Assert(ship_objp->type == OBJ_SHIP); shipp = &Ships[ship_objp->instance]; if ( shipp->flags[Ship::Ship_Flags::Dying] ) { continue; } if ( !(shipp->flags[Ship::Ship_Flags::From_player_wing]) && !(shipp->flags[Ship::Ship_Flags::Red_alert_store_status]) ) { continue; } ras.name = shipp->ship_name; ras.hull = Objects[shipp->objnum].hull_strength; ras.ship_class = shipp->ship_info_index; red_alert_store_weapons(&ras, &shipp->weapons); red_alert_store_subsys_status(&ras, shipp); Red_alert_wingman_status.push_back( ras ); // niffiwan: trying to track down red alert bug creating HUGE pilot files Assert( (Red_alert_wingman_status.size() <= MAX_SHIPS) ); } // store exited ships that did not die for (int idx=0; idx<(int)Ships_exited.size(); idx++) { if (Ships_exited[idx].flags[Ship::Exit_Flags::Red_alert_carry]) { ras.name = Ships_exited[idx].ship_name; ras.hull = float(Ships_exited[idx].hull_strength); // if a ship has been destroyed or removed manually by the player, then mark it as such ... if ( Ships_exited[idx].flags[Ship::Exit_Flags::Destroyed]) { ras.ship_class = RED_ALERT_DESTROYED_SHIP_CLASS; } else if (Ships_exited[idx].flags[Ship::Exit_Flags::Player_deleted]) { ras.ship_class = RED_ALERT_PLAYER_DEL_SHIP_CLASS; } // ... otherwise we want to make sure and carry over the ship class else { Assert( Ships_exited[idx].ship_class >= 0 ); ras.ship_class = Ships_exited[idx].ship_class; } red_alert_store_weapons(&ras, NULL); red_alert_store_subsys_status(&ras, NULL); Red_alert_wingman_status.push_back( ras ); // niffiwan: trying to track down red alert bug creating HUGE pilot files Assert( (Red_alert_wingman_status.size() <= MAX_SHIPS) ); } } Assert( !Red_alert_wingman_status.empty() ); }
/* * red_alert_clear() * * clear all red alert "wingman" data * Allows data to be cleared from outside REDALERT_INTERNAL code */ void red_alert_clear() { Red_alert_wingman_status.clear(); }
/** * Compiles a new shader, and creates an opengl_shader_t that will be put into the GL_shader vector * if compilation is successful. * This function is used for main (i.e. model rendering) and particle shaders, post processing shaders use their own infrastructure * * @param flags Combination of SDR_* flags */ void opengl_compile_main_shader(int flags) { char *vert = NULL, *frag = NULL; mprintf(("Compiling new shader:\n")); bool in_error = false; opengl_shader_t new_shader; // choose appropriate files char vert_name[NAME_LENGTH]; char frag_name[NAME_LENGTH]; if (flags & SDR_FLAG_SOFT_QUAD) { strcpy_s( vert_name, "soft-v.sdr"); strcpy_s( frag_name, "soft-f.sdr"); } else { strcpy_s( vert_name, "main-v.sdr"); strcpy_s( frag_name, "main-f.sdr"); } // read vertex shader if ( (vert = opengl_load_shader(vert_name, flags)) == NULL ) { in_error = true; goto Done; } // read fragment shader if ( (frag = opengl_load_shader(frag_name, flags)) == NULL ) { in_error = true; goto Done; } Verify( vert != NULL ); Verify( frag != NULL ); new_shader.program_id = opengl_shader_create(vert, frag); if ( !new_shader.program_id ) { in_error = true; goto Done; } new_shader.flags = flags; opengl_shader_set_current( &new_shader ); mprintf(("Shader features:\n")); //Init all the uniforms if (new_shader.flags & SDR_FLAG_SOFT_QUAD) { for (int j = 0; j < Particle_shader_flag_references; j++) { if (new_shader.flags == GL_Uniform_Reference_Particle[j].flag) { int k; // Equality check needed because the combination of SDR_FLAG_SOFT_QUAD and SDR_FLAG_DISTORTION define something very different // than just SDR_FLAG_SOFT_QUAD alone for (k = 0; k < GL_Uniform_Reference_Particle[j].num_uniforms; k++) { opengl_shader_init_uniform( GL_Uniform_Reference_Particle[j].uniforms[k] ); } for (k = 0; k < GL_Uniform_Reference_Particle[j].num_attributes; k++) { opengl_shader_init_attribute( GL_Uniform_Reference_Particle[j].attributes[k] ); } mprintf((" %s\n", GL_Uniform_Reference_Particle[j].name)); } } } else { for (int j = 0; j < Main_shader_flag_references; j++) { if (new_shader.flags & GL_Uniform_Reference_Main[j].flag) { if (GL_Uniform_Reference_Main[j].num_uniforms > 0) { for (int k = 0; k < GL_Uniform_Reference_Main[j].num_uniforms; k++) { opengl_shader_init_uniform( GL_Uniform_Reference_Main[j].uniforms[k] ); } } if (GL_Uniform_Reference_Main[j].num_attributes > 0) { for (int k = 0; k < GL_Uniform_Reference_Main[j].num_attributes; k++) { opengl_shader_init_attribute( GL_Uniform_Reference_Main[j].attributes[k] ); } } mprintf((" %s\n", GL_Uniform_Reference_Main[j].name)); } } } opengl_shader_set_current(); // add it to our list of embedded shaders GL_shader.push_back( new_shader ); Done: if (vert != NULL) { vm_free(vert); vert = NULL; } if (frag != NULL) { vm_free(frag); frag = NULL; } if (in_error) { // shut off relevant usage things ... bool dealt_with = false; if (flags & SDR_FLAG_HEIGHT_MAP) { mprintf((" Shader in_error! Disabling height maps!\n")); Cmdline_height = 0; dealt_with = true; } if (flags & SDR_FLAG_NORMAL_MAP) { mprintf((" Shader in_error! Disabling normal maps and height maps!\n")); Cmdline_height = 0; Cmdline_normal = 0; dealt_with = true; } if (!dealt_with) { if (flags == 0) { mprintf((" Shader in_error! Disabling GLSL!\n")); Use_GLSL = 0; Cmdline_height = 0; Cmdline_normal = 0; GL_shader.clear(); } else { // We died on a lighting shader, probably due to instruction count. // Drop down to a special var that will use fixed-function rendering // but still allow for post-processing to work mprintf((" Shader in_error! Disabling GLSL model rendering!\n")); Use_GLSL = 1; Cmdline_height = 0; Cmdline_normal = 0; } } } }