Final tweaks on custom save/load system [SOLVED]

Started by hedgefield, Sat 18/10/2008 22:32:59

Previous topic - Next topic

hedgefield

Hey guys, I'm setting up a custom save/load system for my game in AGS 3.0.2 SP1.
It's based off that 'ole 'Save/load with screenshots' tutorial from way back when, and I had it working fine in AGS 2.62. But since I didn't understand the code 100%, I had to do a bit of guessing when translating it to the new scripting language. It seems to have worked out pretty well though, since the overall system works, but there's just some peculiar things going on with the GUI itself.

1. When I open the save gui, it takes a screenshot and puts it on a button. However, the first time the screenshot does not load. Only when I close the GUI and open it again does it show up. If I moved in the meantime though, I have to close the GUI again and reopen to see THAT screenshot. So the display is always lagging behind.
2. Additionally, the tempsave I make to create that screenshot never gets deleted, even though it says so in the code.
3. When I open the load GUI, I cannot get the screenshot of the top slot to display. If there are multiple savegames in the list, all their screenshots display correctly, except for the top slot. It just returns null on that one.


Here's the relevant code:

The function definitions (@ top of the global script)
Code: ags
//--------------------------------------------------------------------------------------------------------------
// Savegames with screenshots
//--------------------------------------------------------------------------------------------------------------
// Definitions

// Define screenshot width  - 320/5, aka 128 real pixels in 640x480
#define SL_WIDTH  64  
// Define screenshot height - 240/5, aka 96 real pixels in 640x480
#define SL_HEIGHT 48  
// Substitute "139" with the sprite number of your choosing
#define SL_EMPTY_SPRITE 70

// Variables

String text;                                                              // Stores the typed text
int saveslot = 0;                                                         // Stores the selected savegame slot
int saves = 0;                                                            // Stores the total number of savegames
DynamicSprite *screenshot;                                                // Stores the screenshot

// Functions

function sl_save() {
  Wait(1);
  SaveGameSlot(100, "temp");                                              // Save current game in temp slot
  screenshot = DynamicSprite.CreateFromSaveGame(100, SL_WIDTH, SL_HEIGHT);// Retrieve screenshot from save
  DeleteSaveSlot(100);                                                    // Delete temporary slot
  if (screenshot != null) {
    btnSaveScreen.NormalGraphic = screenshot.Graphic;                     // Display current screenshot
  }
  txtSaveName.Text = "";                                                  // Clear Text box
  lstSaveGames.FillSaveGameList();                                        // Fill List Box with saved games
  lstSaveGames.SelectedIndex = -1;                                        // Deselect savegame slots
  saves = lstSaveGames.ItemCount;                                         // Count how many saved games there are         
  if (saves > 19){                                                        // If saved games 20 (maximum)
    Display("All save slots are full. Please overwrite a previous save.");// Display warning
  }
  gSave.Visible = true;                                                   // Opens the save GUI
  gSave.Centre();                                                         // Centres the save GUI
  mouse.Mode = eModePointer;                                              // Set the pointer cursor
}

function sl_load() {
  lstLoadGames.FillSaveGameList();                                        // Fill List Box with saved games
  lstLoadGames.SelectedIndex = -1;                                        // Deselect savegame slots 
  gLoad.Visible = true;                                                   // Opens the load GUI
  gLoad.Centre();                                                         // Centres the load GUI
  mouse.Mode = eModePointer;                                              // Set the pointer cursor
}

//--------------------------------------------------------------------------------------------------------------


The GUI interactions (@ bottom of the global script).
Code: ags
// Save GUI
function btnSaveOK_OnClick(GUIControl *control, MouseButton button) {
  saves = lstSaveGames.ItemCount;                           // Count saved games
  if (saves < 20) {                                         // If less than 50
    text = txtSaveName.Text;                                // Get the typed text
    if (screenshot != null) {
      btnSaveScreen.NormalGraphic = SL_EMPTY_SPRITE;        // Resets the screenshot
      screenshot.Delete();
    }
    gSave.Visible = false;
    mouse.Mode = eModeWalkto;
    Wait(1);
    SaveGameSlot(saves+1,text);                             // Save game (text as description)
  }   
  else {                                                    // If saved games are maxed out (50)
    saveslot = lstSaveGames.SelectedIndex;                  // Get the selected save game
    text = txtSaveName.Text;                                // Get the typed text
    if (screenshot != null) {
      screenshot.Delete();
      btnSaveScreen.NormalGraphic = SL_EMPTY_SPRITE;        // Resets the screenshot
    }
    gSave.Visible = false;
    mouse.Mode = eModeWalkto;
    Wait(1);
    SaveGameSlot(savegameindex[saveslot],text);             // Overwrite the selected game
  }
}

function btnSaveCancel_OnClick(GUIControl *control, MouseButton button) {
  gSave.Visible = false;
  mouse.Mode = eModeWalkto;
  if (screenshot != null) {
    screenshot.Delete();
    btnSaveScreen.NormalGraphic = SL_EMPTY_SPRITE;          // Resets the screenshot
  }
}



// Load GUI
function btnLoadOK_OnClick(GUIControl *control, MouseButton button) {
  saveslot = lstLoadGames.SelectedIndex;                    // Gets the selected slot
  gLoad.Visible = false;
  mouse.Mode = eModeWalkto;
  if (screenshot != null) {
    screenshot.Delete();
    btnLoadScreen.NormalGraphic = SL_EMPTY_SPRITE;          // Resets the screenshot
  }
  RestoreGameSlot(savegameindex[saveslot]);                 // Restores the selected slot
}

function btnLoadCancel_OnClick(GUIControl *control, MouseButton button) {
  gLoad.Visible = false;
  mouse.Mode = eModeWalkto;
  if (screenshot != null) {
    screenshot.Delete();
    btnLoadScreen.NormalGraphic = SL_EMPTY_SPRITE;          // Resets the screenshot
  }
}

function lstLoadGames_OnSelectionChange(GUIControl *control) {
  // Updates screenshot display when selecting a different slot
  saveslot = lstLoadGames.SelectedIndex;                    // Gets the selected slot
  screenshot = DynamicSprite.CreateFromSaveGame(saveslot, SL_WIDTH, SL_HEIGHT);
  if (screenshot != null) {
    btnLoadScreen.NormalGraphic = screenshot.Graphic;       // Updates the screenshot
  }
}


Any thoughts?


[UPDATE]
I've done a bit of further tweaking, and I've discovered some things.
When I delete the tempsave after clicking OK or Cancel on the save GUI instead of right away, it succesfully gets deleted. Side-effect: Now the GUI never shows a screenshot.

Also, something strange happens on the load GUI. I've noticed that the screenshots are sorted in ascending order, with the first one at the top, but the savegames themselves are listed descending, so the most recent one is at the top. So if you save a few times, it sticks the wrong screenshots on the slots.

Pumaman

I think your main problem here is that you're not using the SaveGameSlots array to map between the SelectedIndex and the actual save game number.

For example, this code:

saveslot = lstLoadGames.SelectedIndex;                    // Gets the selected slot
screenshot = DynamicSprite.CreateFromSaveGame(saveslot, SL_WIDTH, SL_HEIGHT);

will get the screenshot for the wrong save game without that mapping.

You do have a couple of references to savegameindex[saveslot] which is the old 2.62 equivalent, but you should replace those with the equivalent  lstLoadGAmes.SaveGAmeSlots  mapping instead.

hedgefield

Ooh thanks, I was wondering about that because I couldn't find savegameindex in the manual. I replaced those references like you said, and in the load GUI SelectionChange I changed:

Code: ags
screenshot = DynamicSprite.CreateFromSaveGame(saveslot, SL_WIDTH, SL_HEIGHT);


to:

Code: ags
screenshot = DynamicSprite.CreateFromSaveGame(lstLoadGames.SaveGameSlots[saveslot], SL_WIDTH, SL_HEIGHT);


Which solved the screenshots displaying wrong. :)

Now to just figure out how to get the screenshot to display right away on the save GUI and I'm all set.

Pumaman

#3
Well, at the moment your code to display the screenshot is in the list box's OnSelectionChange event, so it doesn't get triggered when you first open the GUI.

The easiest thing to do is move the code from your lstLoadGames_OnSelectionChange function into a new function called sl_show_screenshot or something, and then call that new function from OnSelectionChange and also from sl_load.



EDIT: sorry thought you meant Load, not Save GUI.

For the Save GUI the problem is that SaveGameSlot doesn't run immediately, it only runs after the rest of the script finishes. So the save game is from the last time the code ran.

Instead of using SaveGameSlot -> CreateFromSaveGame -> DeleteGameSlot,  just to DynamicSprite.CreateFromScreenSHot instead.

hedgefield

Excellent, thanks CJ. I thought that was what the problem was. Didn't occur to me I can now actually create a screenshot right away without having to save it first. Appreciate the speedy help man.

Dualnames

I've scripted my own savegame gui and well I had the same thing, then replacing that thing fixed it all. Also, I came to notice that if you have screenshots and you haven't enabled screenshots in savegames as a setting, you can still save and occasionally view screenshots but it's weirder since you have the option off.
Worked on Strangeland, Primordia, Hob's Barrow, The Cat Lady, Mage's Initiation, Until I Have You, Downfall, Hunie Pop, and every game in the Wadjet Eye Games catalogue (porting)

SMF spam blocked by CleanTalk