// 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;
}
Example #3
0
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;
}
Example #4
0
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;
}
Example #7
0
	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);
	}
Example #8
0
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();
}