Search code examples
xnasavexbox360content-pipeline

Writing via content pipeline in Xbox game project


I'm creating an Xbox application and I have this problem with the content pipeline. Loading .xnb files is not a problem but I can't seem to find any helpful tutorials on writing via the content pipeline. I want to write an XML whenever the user presses a custom made "save" button. I've searched the web for "saving game sate" etc. but so far I haven't found a solution for my case.

So, summarized: is there a way to write data (in XML format) via the content pipeline, if my Save() method is called?


Solution

  • Saving and loading during an XNA game involves a series of asynchronous method calls. You'll find the objects you need in the Microsoft.Xna.Framework.Storage namespace.

    Specifically, you need a StorageDevice and a StorageContainer;

    private static StorageDevice mStorageDevice;
    private static StorageContainer mStorageContainer;
    

    To Save:

    public static void SaveGame()
    {
       // Call this static method to begin the process; SaveGameDevice is another method in your class
       StorageDevice.BeginShowSelector(SaveGameDevice, null);
    }
    
    // this will be called by XNA sometime after your call to BeginShowSelector
    // SaveGameContainer is another method in your class
    private static void SaveGameDevice(IAsyncResult pAsyncResult)
    {       
       mStorageDevice = StorageDevice.EndShowSelector(pAsyncResult);
       mStorageDevice.BeginOpenContainer("Save1", SaveGameContainer, null);
    }
    
    // this method does the actual saving
    private static void SaveGameContainer(IAsyncResult pAsyncResult)
    {
       mStorageContainer = mStorageDevice.EndOpenContainer(pAsyncResult);
    
       if (mStorageContainer.FileExists("save.dat"))
          mStorageContainer.DeleteFile("save.dat");
    
       // in my case, I have a BinaryWriter wrapper that I use to perform the save
       BinaryWriter writer = new BinaryWriter(new System.IO.BinaryWriter(mStorageContainer.CreateFile("save.dat")));
    
       // I save the gamestate by passing the BinaryWriter
       GameProgram.GameState.SaveBinary(writer);
    
       // then I close the writer
       writer.Close();     
    
       // clean up
       mStorageContainer.Dispose();
       mStorageContainer = null;
    }
    

    Loading is very similar:

    public static void LoadGame()
    {
        StorageDevice.BeginShowSelector(LoadGameDevice, null);
    }
    
    private static void LoadGameDevice(IAsyncResult pAsyncResult)
    {
       mStorageDevice = StorageDevice.EndShowSelector(pAsyncResult);
       mStorageDevice.BeginOpenContainer("Save1", LoadGameContainer, null);
    }
    
    private static void LoadGameContainer(IAsyncResult pAsyncResult)
    {
       mStorageContainer = mStorageDevice.EndOpenContainer(pAsyncResult))
    
       // this is my wrapper of BinaryReader which I use to perform the load
       BinaryReader reader = null;
    
       // the file may not exist
       if (mStorageContainer.FileExists("save.dat"))
       {
          reader = new BinaryReader(new System.IO.BinaryReader(mStorageContainer.OpenFile("save.dat", FileMode.Open)));
    
          // pass the BinaryReader to read the data
          GameProgram.LoadGameState(reader);
          reader.Close();
       }
    
       // clean up
       mStorageContainer.Dispose();
       mStorageContainer = null;
    }