Memory Management Issues

happyturk2 Hokay.

The problem here is that I'm missing a basic understanding of how AGI manages its memory. The specific -issue- is that on the second screen I load, A set of views are supposed to come up to give the option to play the intro, skip straight to the game, restore, or quit, and they -are- rather graphically intensive, but.

It worked before.

That's my main stumping point here- The only thing that's changed since the last time it effectively loaded the views all at once, with no issue, is that I've added a bit of code and two picture files to the tail end of what I have so far. These are not touched between the load of the game and load of screen 2.

Does just the -presense- of added pictures/views/etc reduce the amount of memory the interpreter has to work with? I'd always assumed these things are not a strain on memory until they're called up.

It's calling for 1581 of memory to have them all on at once, with only ~900 available. I attempted to seperate the memory eating loops into a different views so that as they are selected, the view is switched and the animation executed, while the unselected ones sit in low-memory static views, but I can't actually discard the views(causes the game to blitz out into a red mottled screen when I try to select one) so it still wants the same amount of memory.

Any ideas as to how adding elements that will not be loaded runtime until -after- this selection screen could make it run short on memory? I've had this happen before, and futzed with it until it was fixed, but I really -don't- want to cut corners on this one.
sonneveld can you paste the code in a code box?
happyturk2 Okay, need to do this in two posts.

I don't really know how to do a code box, but here.

What I was originally doing was to have views 25-28 be four icons on the screen, each with two loops. One static, one animated, so that when one is selected, it animates and the previous one goes back to being static. Code:

if (f5) {
v120 = 3;
load.pic(v120);
draw.pic(v120);
discard.pic(v120);
set.horizon(50);
status.line.off();
prevent.input();
program.control();
animate.obj(o1);
animate.obj(o2);
animate.obj(o3);
animate.obj(o4);
// 25 - 28 are the icon views
load.view(26);
set.view(o1,26);
load.view(25);
set.view(o2,25);
load.view(27);
set.view(o3,27);
load.view(28);
set.view(o4,28);
position(o1,46,85);
position(o2,82,85);
position(o3,46,142);
position(o4,82,142);
set.loop(o1,1);
draw(o1);
draw(o2);
draw(o3);
draw(o4);
v121=1;
show.pic();
end.of.loop(o1,f120);
set.key(0,66,c41);
set.key(0,68,c40);
display(22,1,"Press f8 to select, f10 to confirm.");
}
if (f120) {
player.control();
}
if (controller(c41)) {
if (v121 == 4) {
// set object four from its animated loop 1 to static loop 0 and set object one to its animated loop 1, same in the rest.
set.loop(o4,0);
set.loop(o1,1);
end.of.loop(o1,f121);
v121=1;
}
else {
if (v121 == 3) {
set.loop(o3,0);
set.loop(o4,1);
end.of.loop(o4,f121);
v121=4;
}
if (v121 == 2) {
set.loop(o2,0);
set.loop(o3,1);
end.of.loop(o3,f121);
v121=3;
}
if (v121 == 1) {
set.loop(o1,0);
set.loop(o2,1);
end.of.loop(o2,f121);
v121=2;
}
}
}
if (controller(c40)){
if (v121 == 1) {
new.room(3);
}
if (v121 == 2) {
accept.input();
status.line.on();
set(f115);
new.room(29);
}
if (v121 == 3) {
restore.game();
}
if (v121 == 4) {
quit(0);
}
}
return();

Now, this worked perfectly, with no issues, until 24 hours ago or so when it started having memory problems. So...
AGI1122 This is a code box: print "I am code"; Just type: [code*]print "I am code";[/code*] but without the asterisks.
happyturk2 I figured I'd make two sets of views. 25-28 remained animated, and 31-34 became the static counterparts. When one is selected, it's switched to the animated view and the old one is switched back to the static view, the animated view discarded. That way, only two animated views at most had to be on the screen at once:

if (f5) {
v120 = 3;
load.pic(v120);
draw.pic(v120);
discard.pic(v120);
set.horizon(50);
status.line.off();
prevent.input();
program.control();
animate.obj(o1);
animate.obj(o2);
animate.obj(o3);
animate.obj(o4);
// start the 1st icon with its animated view, the others with the static
load.view(26);
set.view(o1,26);
load.view(31);
set.view(o2,31);
load.view(33);
set.view(o3,33);
load.view(34);
set.view(o4,34);
position(o1,46,85);
position(o2,82,85);
position(o3,46,142);
position(o4,82,142);
set.loop(o1,1);
draw(o1);
draw(o2);
draw(o3);
draw(o4);
v121=1;
show.pic();
end.of.loop(o1,f120);
set.key(0,66,c41);
set.key(0,68,c40);
display(22,1,"Press f8 to select, f10 to confirm.");
}
if (f120) {
player.control();
}
if (controller(c41)) {
if (v121 == 4) {
// load up o4's static view 34, get rid of animated view 28, and load and assign o1's animated view. The same follows for the rest.
load.view(34);
set.view(o4,34);
discard.view(28);
load.view(26);
set.view(o1,26);
set.loop(o1,1);
force.update(o1);
force.update(o4);
end.of.loop(o1,f121);
v121=1;
}
else {
if (v121 == 3) {
load.view(33);
set.view(o3,33);
discard.view(27);
load.view(28);
set.view(o4,28);
set.loop(o4,1);
force.update(o3);
force.update(o4);
end.of.loop(o4,f121);
v121=4;
}
if (v121 == 2) {
load.view(31);
set.view(o2,31);
discard.view(25);
load.view(27);
set.view(o3,27);
set.loop(o3,1);
force.update(o2);
force.update(o3);
end.of.loop(o3,f121);
v121=3;
}
if (v121 == 1) {
load.view(32);
set.view(o1,32);
discard.view(26);
load.view(25);
set.view(o2,25);
set.loop(o2,1);
force.update(o1);
force.update(o2);
end.of.loop(o2,f121);
v121=2;
}
}
}
if (controller(c40)){
if (v121 == 1) {
new.room(3);
}
if (v121 == 2) {
accept.input();
status.line.on();
set(f115);
new.room(29);
}
if (v121 == 3) {
restore.game();
}
if (v121 == 4) {
quit(0);
}
}
return();

And now, when I load it up, if I hit f8 to go to the second icon the entire screen goes one color with various random streaks of others, and it freezes.

So, any help would be appreciated. I'm mostly just befuddled as to why the original code stopped working, memory-wise, since it worked for so long before and no major changes were made. Mmf.
Kon-Tiki I had that problem with the game freezing and the colours being a disaster too. Try checking if the view has the loops mentioned in the code. I found that it didn't recognize loop 4 or something like that (I've forgotten most of the exact details). It gives some problems and it takes trial and error to figure it out, but it can be the problem.
For the rest: I don't see anything wrong in the code. The memory problem could be because your computer's memory is lessened (although it would be strange to have such low memory that you can't even run AGI)

Hope this helped.
-Kon-Tiki-
happyturk2 Trouble is, it's distinctly the discard.view() commands that are causing the freeze. Becausde if I comment them out and just switch views without discarding them, it eventually runs out of memory(when attempting to go from the 3rd to the 4th icon) but it at least moves from icon to icon without spazzing out or freezing.

Very odd.
Joel there's a good chance that this is the same problem that several other people (including me) have had. look through the old posts on the board for memory issues and there's a good chance you'll find the solution to your problem.
sonneveld for one thing.. you should only call set.key once per GAME.. if you keep on going back to that room, eventually the controller list will fill up.

I can't remember the number, but there's an init logic where all of them get set.. once.

another thing, it's rare but you should only call restore game in logic.0. The reason for this is if you restore a game and the logic you had open isn't open in the exact spot as before, the interpreter *may* crash. the only logic you can be guaranteed to be in the same spot is logic.0 so you might have to set a flag.. and get logic.0 to check for it.. then get logic.0 to restore.

also, if you want to discard/load views.. discard all views *first*.. then load up the ones you want. so maybe set some flags to store which views you have open, discard those first (in reverse order to what you loaded them) and then load up what you want (setting flags as you go along.

see if the last comment helped. the other comments are just to prevent further bugs later on.

I've got an idea for some code, I'll post in a sec.

- Nick
sonneveld Try this, this is if you want to display ONLY a FEW views at a time and want to swap between them. You can't swap between two and then the other two to display on screen

You have to watch out how many times you do this too. Because you'll run out of script.


#define ViewA v25
#define ViewB v26
#define ViewC v27
#define ViewD v28

// these flags only necessary for this room.

// if set, go into function
#define LoadViewFunc f100

// set if view is loaded in memory
#define ViewALoaded f101
// set if you want this view to be loaded.
#define ViewAToLoad f102

#define ViewBLoaded f103
#define ViewBToLoad f104

#define ViewCLoaded f105
#define ViewCToLoad f106

#define ViewDLoaded f107
#define ViewDToLoad f108

// this has to go FIRST
if (newroom)
{
   reset(newroom);
   reset(LoadViewFunc); // so it doesn't get called accidentally
   reset(ViewAToLoad);
   reset(ViewBToLoad);
   reset(ViewCToLoad);
   reset(ViewDToLoad);

   // ......
}


// "function" in logic.. this has to be in the same logic as the one
// it's called in. that way the logic is in memory.
if (LoadViewFunc)
{
   // only call this once.
   reset(LoadViewFunc);

   // discard views in reverse order to what they were loaded in
   if (ViewDLoaded) { discard.view(ViewD); }
   if (ViewCLoaded) { discard.view(ViewC); }
   if (ViewBLoaded) { discard.view(ViewB); }
   if (ViewALoaded) { discard.view(ViewA); }

   // load each view in normal order. set flags for later
   if (ViewAToLoad)
      { load.view(ViewA); set(ViewALoaded); }
   else
      { reset(ViewALoaded); }
   if (ViewBToLoad)
      { load.view(ViewB); set(ViewBLoaded); }
   else
      { reset(ViewBLoaded); }
   if (ViewCToLoad)
      { load.view(ViewC); set(ViewCLoaded); }
   else
      { reset(ViewCLoaded); }
   if (ViewDToLoad)
      { load.view(ViewD); set(ViewDLoaded); }
   else
      { reset(ViewDLoaded); }
   
   // that way we only have to set the ones to load.
   reset(ViewAToLoad);
   reset(ViewBToLoad);
   reset(ViewCToLoad);
   reset(ViewDToLoad);

   return; // we want to return to original position in logic.
}


// other code

if (something)
{
   set(ViewAToLoad);
   set(ViewBToLoad);
   set(LoadViewFunc);   // all views discarded, A,B loaded
   call(v0); // has to be current logic.. important

   set.view(o10, ViewA);
   set.view(o11, ViewB);   
}

if (somethingelse)
{
   set(ViewBToLoad);
   set(ViewDToLoad);
   set(LoadViewFunc);   // all views discarded, B,D loaded
   call(v0); // has to be current logic.. important

   set.view(o10, ViewB);
   set.view(o11, ViewD);   
}




- Nick
happyturk2 I appreciate the input, and I'll remedy those first two issues to prevent unpredictable behavior in future.

As for the view switching... I attempted to have it erase the objects on each switch and redraw them all; this is obvious an inelegant solution at best, brute force doomed to overflow the buffer at worst, and it did.

So.

What I ended up doing was simply drawing the static views on the screen, and loading all of the animations into one view as seperate loops. One object that moves from position to position and switches loops as need be. Not sure why it didn't occur to me before.

I will analyze this code you've provided though, because as with any programming language, this is as much about how to think correctly as it is about how to get it to do what you want.
Andrew_Baker Not sure how much help it would be, but instead of switching loops, you can have one loop whose static state will cause it to stop.cycling(), and its animated state will cause it to start.cycling(). This will free up a little bit of view memory, although it will be a trivial amount. Also, when I'm doing large animated sequences that hog memory, like swapping between pics in the same room, I call new.room(). This will give you some stack memory back, although it can sometimes cause flicker.