Author Topic: LoadSaveSlotScreenshot and DynamicSprite.CreateFromSaveGame  (Read 934 times)  Share 

ZakMcKracken

  • ZLORFIK! I missed him!
Hello,

I'm creating a new Save/Load GUI with screenshots.
Since I haven't created one before, I looked for a good tutorial, and found this one:
http://www.twin-design.com/agsezine/9/tutorial.cfm
(this is Scripting Tutorial By Andrew McCormack)

It says the tutorial will present how to make a load/save game dialog that uses the new "save games with screenshots" feature of AGS v2.6 onward.

Well... I'm using AGS 2.7, I did the tutorial step-by-step, but when I save the game, the compiler stops with message "undefined symbol LoadSaveSlotScreenshot'":
[code]
function sgs_getslots()
{
int i=1;
while(i<=6)
   {
   if (GetSaveSlotDescription(i, sgs_struct.t))
      {
      sgs_struct.spr=LoadSaveSlotScreenshot(i, SGS_WIDTH, SGS_HEIGHT);
      }
   else
      {
      StrCopy(sgs_struct.t, "");
      sgs_struct.spr=SGS_EMPTY_SPRITE;
      }
   SetLabelText(SAVELOAD, 6+i, sgs_struct.t);
   SetLabelColor(SAVELOAD, 6+i, SGS_LABEL_COLOUR);
   SetButtonPic(SAVELOAD, i, 1, sgs_struct.spr);
   i=i+1;
   }
Wait(1);
SaveGameSlot(100, "temp");
sgs_struct[0].spr=LoadSaveSlotScreenshot(100, SGS_WIDTH, SGS_HEIGHT);
DeleteSaveSlot(100);
}
[/code]

Well, the help file says that LoadSaveSlotScreenshot is obsolete, and suggests to use DynamicSprite.CreateFromSaveGame

I tried, but with no success. I changed the int to DynamicSprite*, but it doesn't compile.

Can someone clarify the concepts?
I think the tutorial is very very good, maybe it could be more useful fix the tutorial to make it compatible with AGS 2.7

Thank you.

monkey_05_06

  • AGS Project Admins
  • #1 Straight Basher
Change the lines that read:

[code]sgs_struct
  • .spr=LoadSaveSlotScreenshot(#, SGS_WIDTH, SGS_HEIGHT);[/code]

    To:

[code]DynamicSprite* spr = DynamicSprite.CreateFromSaveGame(#, SGS_WIDTH, SGS_HEIGHT);
sgs_struct
  • .spr = spr.ID;[/code]

    Leave sgs_struct[ # ].spr defined as an int.  And be sure to replace # with the appropriate numbers and not just copy and paste o_0.

    Edit:  Apparently a '[' followed by a '#' and a ']' creates the bullet sprite
  • .  I didn't know that...
  • [/list]

    Edit:  Allong with forcing the bulleted text to the next line.
    « Last Edit: 16 Jul 2005, 00:58 by monkey_05_06 »
    By and large I didn't accomplish what I set out to do, but I did accomplish a fair bit. So, there is that.

    ZakMcKracken

    • ZLORFIK! I missed him!
    Hello monkey,

    thank you for your support.
    Unfortunately, the compiler says "ID is not a member of spr". I tryed to write it in lowercase, too.

    Anyway, I attempted a workaround.
    I loaded AGS 2.62 in a separate directory, and created the Save/Load GUI according to the tutorial.
    Everything works fine  :=
    So, I saved everything, then I loaded AGS 2.7, and loaded my game with the new GUI.

    The room conversion has been applied, as usual, and when I look into the Global Script to see if something has changed, I surprisingly notice that everything was untouched!  :o
    There are "LoadSaveSlotScreenshot" function calls, and... they works! The compiler compiles the game, and when I test it, it works. The screenshots appear.

    I can't figure out why, yesterday, the compiler told me "undefined symbol LoadSaveSlotScreenshot'"...

    Well, to be honest, there is a little thing that doesn't work: the very first time I save a game, it crashes indicating that I attempted to delete a sprite that was not allocated.
    But the game saves correctly in its slot.
    Then, every time I run the game, and save, everything is right.

    Maybe it could be useful to change all obsolete functions into the new logic; if I succeed in, I'll post the changes.

    Regards

    Pumaman

    • Creator of AGS
    • Administrator
    • Mittens TRAITOR
    • I sense danger.
      • Lifetime Achievement Award Winner
      •  
    2.7 can be backwards compatible with 2.62 and support all the old-style commands, if "Enforce object-based scripting" is not checked in the General Settings tab.

    By default in a new game backwards compatibility is disabled, but if you upgrade a game from 2.62 it is enabled. You can toggle the checkbox to change it yourself.

    ZakMcKracken

    • ZLORFIK! I missed him!
    Hello Pumaman,

    you are right, mistery solved. It was the "Enforce object-based scripting" option!

    Thank you.

    monkey_05_06

    • AGS Project Admins
    • #1 Straight Basher
    But it gets confusing using both... Sorry I didn't look up the right property name.  I just assumed it would be ID for some reason...  The proper name would be spr.Graphic...but I guess you're just going to use the old-style code amongst new-style...
    By and large I didn't accomplish what I set out to do, but I did accomplish a fair bit. So, there is that.

    ZakMcKracken

    • ZLORFIK! I missed him!
    Hello Monkey,

    no, no, I am trying to translate into the new object-oriented style. So, every clue is welcome  :)

    I use the old style just to better understand the concepts and logic, but my final goal is to make a game enterely object-based.

    Regards

    monkey_05_06

    • AGS Project Admins
    • #1 Straight Basher
    Okay, then you may want to use the code I posted, and just change "ID" to "Graphic".  In case you didn't already figure it out.  Sorry that I just made up the property name.  I was kind of tired and a lot of the new object types have ID properties (Hotspot, Object, Character, etc.).  I should have paid better attention when I was looking up the proper parameter list.

    ~Cheers
    By and large I didn't accomplish what I set out to do, but I did accomplish a fair bit. So, there is that.

    ZakMcKracken

    • ZLORFIK! I missed him!
    Hello everybody,

    Now I have understand, but there is just one more thing that puzzles me.

    In AGS 2.62, the following lines...
    [code]
    SaveGameSlot(100, "temp"); // Save current game in temp slot
    sgs_struct[0].spr=LoadSaveSlotScreenshot(100, SGS_WIDTH, SGS_HEIGHT); // load up screenshot
    DeleteSaveSlot(100); // Delete temporary slot
    [/code]
    ...work fine: in sgs_struct[0].spr there is a value.
    In fact, the subsequent instruction:
    [code]
    SetButtonPic(SAVELOAD, button, 1, sgs_struct[0].spr); // change selected button to have current game screenshot
    [/code]
    works fine as well: in my button, I see the picture.

    Same code, compiled with AGS 2.7: when I click on the button, it shows me anything, and the game crashes. It seems it can't load the sprite from the temporary saved game slot.
    The option "Save screenshot in save game" is checked.

    Well, I changed the above lines as follow:
    [code]
    SaveGameSlot(100, "temp"); // Save current game in temp slot
    DynamicSprite* spr = DynamicSprite.CreateFromSaveGame(100, SGS_WIDTH, SGS_HEIGHT);
    sgs_struct[0].spr=spr.Graphic;
    spr.Delete();
    DeleteSaveSlot(100); // Delete temporary slot
    [/code]
    ...and when the code is executed in the game, it crashes with the error: "null pointer referenced", and the line number indicates the assignment: "sgs_struct[0].spr=spr.Graphic;".

    I checked again the option "Save screenshot in save game"... and it's turned on.

    I could suppose there is a bug in SaveGameSlot function, but I don't think so: if I run the game with the original lines of code (that is using LoadSaveSlotScreenshot), the game crashes the first time I try to save, but if I run the game again, and try to save, I see a picture in a slot. So, I assume that a sprite as been saved with the slot.

    I don't know... it seems like the slot 100 is unpleasant to AGS :-)
    Can someone try to see if SaveGameSlot(100, "temp") saves the screenshot correctly?

    Thank you

    Iceboty V7000a

    • Local Moderator
    • * KILL* * KILL * * KILL *
      • Lifetime Achievement Award Winner
      •  
    I think that's because you deleted the sprite from memory:
    spr.Delete();

    sgs_struct[0].spr originally points to a sprite number (i suppose) which no longer exists after the deletion of spr.

    ZakMcKracken

    • ZLORFIK! I missed him!
    Hello,

    wow, Gilbot, what a speedy!! :D  I just came in to add further information to my case.

    When I compile the original code with AGS 2.7, the game crashes when attempting to execute the following line:
    [code]
    if (sgs_struct.spr != SGS_EMPTY_SPRITE) DeleteSprite(sgs_struct.spr); //SGS_EMPTY_SPRITE is defined as 139, which is a sprite in the library with a picture saying "Empty slot"
    [/code]
    with the message "Attempted to free a static sprite that was not loaded by the script".
    Same code, in AGS 2.62, works fine.


    In conclusion, the differences betweeen 2.62 and 2.7 (executing the same code):

    [code]
    SaveGameSlot(100, "temp"); // Save current game in temp slot
    sgs_struct[0].spr=LoadSaveSlotScreenshot(100, SGS_WIDTH, SGS_HEIGHT); // load up screenshot
    DeleteSaveSlot(100); // Delete temporary slot
    ...
    SetButtonPic(SAVELOAD, button, 1, sgs_struct[0].spr); // change selected button to have current game screenshot
    ...
    int i=0;
    while(i<=6)
      {
      if (sgs_struct.spr != SGS_EMPTY_SPRITE) DeleteSprite(sgs_struct.spr);
      i=i+1;
      }
    [/code]

    ...with AGS 2.62 everything is allright:
    • Loads a sprite number into sgs_struct[0].spr
    • Sets the image when I first click on the button
    • Deletes the sprite from sgs_struct[0].spr


    ...with AGS 2.7 something is wrong:
    • sgs_struct[0].spr is 0
    • There is no image in the button
    • When attempting to delete sgs_struct[0].spr (which value is 0), it crashes with the error "Attempted to free a static sprite that was not loaded by the script".


    Hope this could be useful.

    Thank you everybody!
    Regards

    Iceboty V7000a

    • Local Moderator
    • * KILL* * KILL * * KILL *
      • Lifetime Achievement Award Winner
      •  
    Let me see if I can help.

    1. In V2.7+, to make a screenshot sprite, you don't need to do the workaround of making a temp save game anymore, check out the sprite function CreateFromScreenShot() from the manual.

    2. Since in V2.7+ you're more recommended to use the pointerish function Sprite.Delete() rather than the old functions DeleteSprite() and LoadSaveSlotScreenshot(), etc., which work on sprite number.
    From the manual, it seems that you have to work past one problem:
    Quote
    IMPORTANT: If the DynamicSprite instance is released from memory (ie. there is no longer a DynamicSprite* variable pointing to it), then the sprite will also be removed from memory. Make sure that you keep a global variable pointer to the sprite until you are finished with it, and at that point call Delete.
    That is, if you create a dynamic sprite you must define a DynamicSprite* pointer to hold it, whereas:
    - If you define a DynamicSprite* pointer inside of a function, make sure that the sprite is only used  inside the scoop of that function (otherwise the game may not work if you still want it outside of this function), since the variable will be destroyed (alongside with the sprite) when the function ends, so if you want to use it somewhere else, declare this variable outside of the function, on top of the script.
    - Since old functions like LoadSaveSlotScreenshot() don't return a DynamicSprite* pointer, they're probably obsolete and won't work now, since you need to keep a copy of that pointer for the sprite to stay.

    Either way, what I think is that, unless you really need to, you don't normally need to delete the sprites yourself, since they'll be taken of by the engine automagically most of the time.

    ZakMcKracken

    • ZLORFIK! I missed him!
    Thank you very much, Gilbot.

    I defined a DynamicSprite* variable outside my functions, and used CreateFromScreenShot and CreateFromSaveGame to set and load screenshots.

    Then I set that variable to null, so the allocated memory can be freed.

    Now it works.

    Well, I just test it and as soon as possible I'll make a tutorial, to create a Save/Load GUI with screenshots using AGS 2.7

    Regards

    SSH

    • Flying round the world at the speed of haggis
      • I can help with scripting
      •  
    • SSH worked on a game that was nominated for an AGS Award!
    Ooops, sorry, I could have told you most of that staright away but I've been away... since I wrote the tutorial.

    Actually, if you look at the source code for the game Pixel Hunt, there is a 2.7 compatible version of the same code.


    monkey_05_06

    • AGS Project Admins
    • #1 Straight Basher
    I forgot to say that when working with a pointer, such as:

    [code]DynamicSprite* spr = DynamicSprite.CreateFromSaveGame(...);[/code]

    That you should test to make sure that the object pointed to exists:

    [code]if (spr != null) { /* do stuff */ }[/code]
    By and large I didn't accomplish what I set out to do, but I did accomplish a fair bit. So, there is that.

    ZakMcKracken

    • ZLORFIK! I missed him!
    Hello SSH,

    thank you very much for your help. I downloaded source code of your game, you are great!
    First of all, because you produced 2 distinct modules, and second... it works perfectly!

    Thank you everybody.

    Regards.

    simulacra

    • Read between the lines
      • I can help with translating
      •  
      • I can help with voice acting
      •  
    I have intensely studied the pixel hunt code as well as this thread and tried unsuccessfully to modify the old sgs to work in 2.7. I think that the problem is that I do not know what I am doing.

    [code]function sgs_getslots()
    {
    int i=1; // Loop counter starts at 1
    while(i<=6) { // Count from 1 to 6
    if (GetSaveSlotDescription(i, sgs_struct.t)) { // Slot exists
    sgs_struct.spr=DynamicSprite.CreateFromSaveGame(i, SGS_WIDTH, SGS_HEIGHT);

    } else { // There is no saved game for this slot
    StrCopy(sgs_struct.t, ""); // Blank description
    sgs_struct.spr=SGS_EMPTY_SPRITE; // Empty sprite
    }
    SetLabelText(SAVELOAD, 6+i, sgs_struct.t); // Set GUI label to description
    SetLabelColor(SAVELOAD, 6+i, SGS_LABEL_COLOUR); // Set GUI label colour
    SetButtonPic(SAVELOAD, i, 1, sgs_struct.spr); // Set button to have screenshot pic
    i=i+1; // next slot
    }
    // Get current game ss, too
    Wait(1); // make sure screen is updated
    //SaveGameSlot(100, "temp"); // Save current game in temp slot
    //Wait(20);
    //sgs_struct[0].spr=DynamicSprite.CreateFromScreenShot(SGS_WIDTH, SGS_HEIGHT); // load up screenshot
    //DeleteSaveSlot(100); // Delete temporary slot
    sgs_sprite = DynamicSprite.CreateFromScreenShot(SGS_WIDTH, SGS_HEIGHT);
    }
    [/code]

    The first highlighted line gives me an error about trying to assign a sprite to an int. I guess I must have mixed apples and pears, but what do I do instead?

    I commented out the old-school code and tried to replace it with what I think is a pointer to a dynamic sprite.

    I am really have angst regarding this as I am supposed to hand the project over to the printer at friday and spent several days messing this up even further.  :'(

    Interested in philosophy, metaphysics and artsy things? You should explore The Zone, a quite different adventure game. http://www.interactingarts.org/thezone/

    SSH

    • Flying round the world at the speed of haggis
      • I can help with scripting
      •  
    • SSH worked on a game that was nominated for an AGS Award!
    The latest beta of my modules to do these are available here, along with some other crap: http://www.lumpcity.co.uk/~ssh/sgs_gue_prob.rar

    but make sure you use latest beta AGS  as the GUE import is broken pre 2.71 beta 5. If you must try with an earlier version, make sure you back up your game files first, as the broken GUE import can totally screw up a game.

    As for your code, sim, DynamicSprite functions return a DynamicSprite * which I used the array dspr for in my  Pixel Hunt code that you have. so replace sgs_struct.spr with dspr on the first line (that bold doesnt work, btw)

    I'm just adjusting the modules to use new strings and I should be done.
    « Last Edit: 06 Sep 2005, 20:21 by SSH »

    simulacra

    • Read between the lines
      • I can help with translating
      •  
      • I can help with voice acting
      •  
    I see.

    The line:

    [code]    AskYesNo("Overwrite savegame?");[/code]

    Causes a type mismatch error "cannot convert const string to string".  :-\

    Interested in philosophy, metaphysics and artsy things? You should explore The Zone, a quite different adventure game. http://www.interactingarts.org/thezone/

    SSH

    • Flying round the world at the speed of haggis
      • I can help with scripting
      •  
    • SSH worked on a game that was nominated for an AGS Award!
    Yeah, change all the string parameters of functions to const string.... see the beta thread for CJ's explanation