// Analogous to 'save_game()', but does not present any dialog to the user, and reports the results // using screen_printf(). If inOverwriteRecent is set, it will save over the most recently saved // or restored game (if possible). If inOverwriteRecent is not set, or if there is no recent game // to save over, it will pick a new, nonconflicting filename and save to it. // Returns whether save was successful. bool save_game_full_auto(bool inOverwriteRecent) { bool createNewFile = !inOverwriteRecent; FileSpecifier theRecentSavedGame; get_current_saved_game_name(theRecentSavedGame); char theSavedGameName[256]; // XXX // If we're supposed to overwrite, change our minds if we seem to have no 'existing file'. if(!createNewFile) { theRecentSavedGame.GetName(theSavedGameName); if(strcmp(theSavedGameName, TS_GetCString(strFILENAMES, filenameDEFAULT_SAVE_GAME)) == 0) createNewFile = true; } // Make up a filename (currently based on level name) if(createNewFile) { if(strncpy_filename_friendly(theSavedGameName, static_world->level_name, kMaxFilenameChars) <= 0) strcpy(theSavedGameName, "Automatic Save"); DirectorySpecifier theDirectory; theRecentSavedGame.ToDirectory(theDirectory); theRecentSavedGame.FromDirectory(theDirectory); #if defined(mac) || defined(SDL_RFORK_HACK) // Note: SetName() currently ignores the 'type' argument, so I feel // little compulsion to try to figure it out. theRecentSavedGame.SetName(theSavedGameName,NONE); #else theRecentSavedGame.AddPart(theSavedGameName); #endif } FileSpecifier theOutputFile; if(createNewFile) make_nonconflicting_filename_variant(theRecentSavedGame, theOutputFile, kMaxFilenameChars); else theOutputFile = theRecentSavedGame; bool successfulSave = save_game_file(theOutputFile); theOutputFile.GetName(theSavedGameName); if(successfulSave) { screen_printf("%s saved game '%s'", createNewFile ? "Created new" : "Replaced existing", theSavedGameName); // play a sound? } else { screen_printf("Unable to save game as '%s'", theSavedGameName); // play a sound? } return successfulSave; }
bool save_game( void) { pause_game(); show_cursor(); /* Translate the name, and display the dialog */ FileSpecifier SaveFile; get_current_saved_game_name(SaveFile); char GameName[256]; SaveFile.GetName(GameName); char Prompt[256]; // Must allow the sound to play in the background bool success = SaveFile.WriteDialogAsync( _typecode_savegame, getcstr(Prompt, strPROMPTS, _save_game_prompt), GameName); if (success) success = save_game_file(SaveFile); hide_cursor(); resume_game(); return success; }
bool XML_Loader_SDL::ParseFile(FileSpecifier &file_name) { // Open file OpenedFile file; if (file_name.Open(file)) { printf ( "Parsing: %s\n", file_name.GetPath() ); // Get file size and allocate buffer file.GetLength(data_size); data = new char[data_size]; // In case there were errors... file_name.GetName(FileName); // Read and parse file if (file.Read(data_size, data)) { if (!DoParse()) { fprintf(stderr, "There were parsing errors in configuration file %s\n", FileName); } } // Delete buffer delete[] data; data = NULL; return true; } else { printf ( "Couldn't open: %s\n", file_name.GetPath() ); } return false; }
static bool confirm_save_choice(FileSpecifier & file) { // If the file doesn't exist, everything is alright if (!file.Exists()) return true; // Construct message char name[256]; file.GetName(name); char message[512]; sprintf(message, "'%s' already exists.", name); // Create dialog dialog d; vertical_placer *placer = new vertical_placer; placer->dual_add(new w_static_text(message), d); placer->dual_add(new w_static_text("Ok to overwrite?"), d); placer->add(new w_spacer(), true); horizontal_placer *button_placer = new horizontal_placer; w_button *default_button = new w_button("YES", dialog_ok, &d); button_placer->dual_add(default_button, d); button_placer->dual_add(new w_button("NO", dialog_cancel, &d), d); placer->add(button_placer, true); d.activate_widget(default_button); d.set_widget_placer(placer); // Run dialog return d.run() == 0; }
bool LoadModel_Studio(FileSpecifier& Spec, Model3D& Model) { ModelPtr = &Model; Model.Clear(); if (DBOut) { // Name buffer const int BufferSize = 256; char Buffer[BufferSize]; Spec.GetName(Buffer); fprintf(DBOut,"Loading 3D Studio Max model file %s\n",Buffer); } OpenedFile OFile; if (!Spec.Open(OFile)) { if (DBOut) fprintf(DBOut,"ERROR opening the file\n"); return false; } ChunkHeaderData ChunkHeader; if (!ReadChunkHeader(OFile,ChunkHeader)) return false; if (ChunkHeader.ID != MASTER) { if (DBOut) fprintf(DBOut,"ERROR: not a 3DS Max model file\n"); return false; } if (!ReadContainer(OFile,ChunkHeader,ReadMaster)) return false; return (!Model.Positions.empty() && !Model.VertIndices.empty()); }
// This tries to find a filename (in the same directory as inBaseName) based on 'inBaseName' but that is not yet used. // The current logic tries inBaseName first, then 'inBaseName 2', then 'inBaseName 3', and so on. // The resulting name will have no more than inMaxNameLength actual characters. // Returns whether it was successful (the current logic either returns true or loops forever; fortunately, the // probability of looping forever is really, REALLY tiny; the directory would have to contain every possible variant). static bool make_nonconflicting_filename_variant(/*const*/ FileSpecifier& inBaseName, FileSpecifier& outNonconflictingName, size_t inMaxNameLength) { FileSpecifier theNameToTry; DirectorySpecifier theDirectory; inBaseName.ToDirectory(theDirectory); char theBaseNameString[256]; // XXX I don't like this, but the SDL code already imposes this maxlen throughout. inBaseName.GetName(theBaseNameString); size_t theBaseNameLength = strlen(theBaseNameString); char theNameToTryString[256]; char theVariantSuffix[32]; // way more than enough unsigned int theVariant = 0; size_t theSuffixLength; size_t theBaseNameLengthToUse; bool theVariantIsAcceptable = false; while(!theVariantIsAcceptable) { theVariant++; if(theVariant == 1) { theVariantSuffix[0] = '\0'; theSuffixLength = 0; } else { theSuffixLength = sprintf(theVariantSuffix, " %d", theVariant); } assert(theSuffixLength <= inMaxNameLength); if(theSuffixLength + theBaseNameLength > inMaxNameLength) theBaseNameLengthToUse = inMaxNameLength - theSuffixLength; else theBaseNameLengthToUse = theBaseNameLength; sprintf(theNameToTryString, "%.*s%s", (int) theBaseNameLengthToUse, theBaseNameString, theVariantSuffix); theNameToTry.FromDirectory(theDirectory); #if defined(mac) || defined(SDL_RFORK_HACK) // Note: SetName() currently ignores the 'type' argument, so I feel // little compulsion to try to figure it out. theNameToTry.SetName(theNameToTryString,NONE); #else theNameToTry.AddPart(theNameToTryString); #endif if(!theNameToTry.Exists()) theVariantIsAcceptable = true; } if(theVariantIsAcceptable) { outNonconflictingName = theNameToTry; } return theVariantIsAcceptable; }
void Init(const FileSpecifier& dir, w_directory_browsing_list::SortOrder default_order, std::string filename) { m_sort_by_w = new w_select(static_cast<size_t>(default_order), sort_by_labels); m_sort_by_w->set_selection_changed_callback(boost::bind(&FileDialog::on_change_sort_order, this)); m_up_button_w = new w_button("UP", boost::bind(&FileDialog::on_up, this)); if (filename.empty()) { m_list_w = new w_directory_browsing_list(dir, &m_dialog); } else { m_list_w = new w_directory_browsing_list(dir, &m_dialog, filename); } m_list_w->sort_by(default_order); m_list_w->set_directory_changed_callback(boost::bind(&FileDialog::on_directory_changed, this)); dir.GetName(temporary); m_directory_name_w = new w_static_text(temporary); }
void dump_screen(void) { // Find suitable file name FileSpecifier file; int i = 0; do { char name[256]; const char* suffix; #ifdef HAVE_PNG suffix = "png"; #else suffix = "bmp"; #endif if (get_game_state() == _game_in_progress) { sprintf(name, "%s_%04d.%s", to_alnum(static_world->level_name).c_str(), i, suffix); } else { sprintf(name, "Screenshot_%04d.%s", i, suffix); } file = screenshots_dir + name; i++; } while (file.Exists()); #ifdef HAVE_PNG // build some nice metadata std::vector<IMG_PNG_text> texts; std::map<std::string, std::string> metadata; metadata["Source"] = expand_app_variables("$appName$ $appVersion$ ($appPlatform$)"); time_t rawtime; time(&rawtime); char time_string[32]; strftime(time_string, 32,"%d %b %Y %H:%M:%S +0000", gmtime(&rawtime)); metadata["Creation Time"] = time_string; if (get_game_state() == _game_in_progress) { const float FLOAT_WORLD_ONE = float(WORLD_ONE); const float AngleConvert = 360/float(FULL_CIRCLE); metadata["Level"] = static_world->level_name; char map_file_name[256]; FileSpecifier fs = environment_preferences->map_file; fs.GetName(map_file_name); metadata["Map File"] = map_file_name; if (Scenario::instance()->GetName().size()) { metadata["Scenario"] = Scenario::instance()->GetName(); } metadata["Polygon"] = boost::lexical_cast<std::string>(world_view->origin_polygon_index); metadata["X"] = boost::lexical_cast<std::string>(world_view->origin.x / FLOAT_WORLD_ONE); metadata["Y"] = boost::lexical_cast<std::string>(world_view->origin.y / FLOAT_WORLD_ONE); metadata["Z"] = boost::lexical_cast<std::string>(world_view->origin.z / FLOAT_WORLD_ONE); metadata["Yaw"] = boost::lexical_cast<std::string>(world_view->yaw * AngleConvert); short pitch = world_view->pitch; if (pitch > HALF_CIRCLE) pitch -= HALF_CIRCLE; metadata["Pitch"] = boost::lexical_cast<std::string>(pitch * AngleConvert); } for (std::map<std::string, std::string>::const_iterator it = metadata.begin(); it != metadata.end(); ++it) { IMG_PNG_text text; text.key = const_cast<char*>(it->first.c_str()); text.value = const_cast<char*>(it->second.c_str()); texts.push_back(text); } IMG_PNG_text* textp = texts.size() ? &texts[0] : 0; #endif // Without OpenGL, dumping the screen is easy if (!MainScreenIsOpenGL()) { //#ifdef HAVE_PNG // aoIMG_SavePNG(file.GetPath(), MainScreenSurface(), IMG_COMPRESS_DEFAULT, textp, texts.size()); #ifdef HAVE_SDL_IMAGE IMG_SavePNG(MainScreenSurface(), file.GetPath()); #else SDL_SaveBMP(MainScreenSurface(), file.GetPath()); #endif return; } int video_w = MainScreenPixelWidth(); int video_h = MainScreenPixelHeight(); #ifdef HAVE_OPENGL // Otherwise, allocate temporary surface... SDL_Surface *t = SDL_CreateRGBSurface(SDL_SWSURFACE, video_w, video_h, 24, #if SDL_BYTEORDER == SDL_LIL_ENDIAN 0x000000ff, 0x0000ff00, 0x00ff0000, 0); #else 0x00ff0000, 0x0000ff00, 0x000000ff, 0); #endif if (t == NULL) return; // ...and pixel buffer void *pixels = malloc(video_w * video_h * 3); if (pixels == NULL) { SDL_FreeSurface(t); return; } // Read OpenGL frame buffer glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, video_w, video_h, GL_RGB, GL_UNSIGNED_BYTE, pixels); glPixelStorei(GL_PACK_ALIGNMENT, 4); // return to default // Copy pixel buffer (which is upside-down) to surface for (int y = 0; y < video_h; y++) memcpy((uint8 *)t->pixels + t->pitch * y, (uint8 *)pixels + video_w * 3 * (video_h - y - 1), video_w * 3); free(pixels); // Save surface //#ifdef HAVE_PNG // aoIMG_SavePNG(file.GetPath(), t, IMG_COMPRESS_DEFAULT, textp, texts.size()); #ifdef HAVE_SDL_IMAGE IMG_SavePNG(t, file.GetPath()); #else SDL_SaveBMP(t, file.GetPath()); #endif SDL_FreeSurface(t); #endif }
bool LoadModel_QD3D(FileSpecifier& Spec, Model3D& Model) { // Clear out the final model object Model.Clear(); // Test for QD3D/Quesa's presence and initialize it if not present if (QD3D_Presence_Checked) { if (!QD3D_Present) return false; } else { QD3D_Presence_Checked = true; // MacOS QD3D; modify this for Quesa as appropriate if ((void*)Q3Initialize != (void*)kUnresolvedCFragSymbolAddress) { TQ3Status Success = Q3Initialize(); QD3D_Present = (Success == kQ3Success); } // Do additional setup; // if the triangulator could not be created, then act as if // QD3D/Quesa had not been loaded if (QD3D_Present) { Q3Error_Register(QD3D_Error_Handler,0); QD3D_Present = CreateTriangulator(); } if (!QD3D_Present) Q3Exit(); } if (DBOut) { // Read buffer const int BufferSize = 256; char Buffer[BufferSize]; Spec.GetName(Buffer); fprintf(DBOut,"Loading QuickDraw-3D model file %s\n",Buffer); } TQ3Object ModelObject = LoadModel(Spec); if (!ModelObject) return false; StartAccumulatingVertices(); if (Q3View_StartRendering(TriangulatorView) == kQ3Failure) { if (DBOut) fprintf(DBOut,"ERROR: couldn't start triangulation 'rendering'\n"); Q3Object_Dispose(ModelObject); return false; } do { Q3SubdivisionStyle_Submit(&TesselationData, TriangulatorView); if (Q3Object_Submit(ModelObject, TriangulatorView) == kQ3Failure) { if (DBOut) fprintf(DBOut,"ERROR: model could not be 'rendered'\n"); } } while (Q3View_EndRendering(TriangulatorView) == kQ3ViewStatusRetraverse); // Done with the model Q3Object_Dispose(ModelObject); GetVerticesIntoModel(Model); return !Model.Positions.empty(); }