Adventure Game Studio

AGS Support => Beginners' Technical Questions => Topic started by: Hernald on Fri 05/07/2013 00:18:07

Title: SOLVED: How do I fool the while loop iteration limit?
Post by: Hernald on Fri 05/07/2013 00:18:07
I am trying to write a function creates a map of the hotspots in a room and sends it to a .bmp file.
The function GrabHotspots(); is placed in the code of room to be mapped to run after the room has become visible.
The trouble is that if the room is much larger than 320*240 pixels the process crashes as the iterations exceed 150,000.
I've tried to fool it by having the code in blocks and breaking out when the room has been scanned - returning instead of using a while loop; but it still doesn't work. Any suggestions?

Code (AGS) Select

DynamicSprite* theroom;
DrawingSurface* themask;

int roomwidth;
int roomheight;

Hotspot* hot;

function DrawBlock(int xfrom, int yfrom, int xto, int yto) {
int xcount;
int ycount;

xcount = xfrom;
while (xcount<xto) {
ycount = yfrom;
while (ycount<yto) {
hot = Hotspot.GetAtScreenXY(xcount, ycount);
themask.DrawingColor = hot.ID;
themask.DrawPixel(xcount, ycount);
ycount++;
}
xcount++;
}
}

function BlocksAcross(int ystart) {
int thiswidth;

int thisheight=ystart+240;
if (roomheight<thisheight) thisheight = roomheight;

int xstart = 0;
thiswidth = 320;
if (roomwidth<thiswidth)thiswidth = roomwidth;
DrawBlock(xstart, ystart, thiswidth, thisheight);
if (thiswidth==roomwidth) return;

xstart+=320;
thiswidth +=320;
if (roomwidth<thiswidth)thiswidth = roomwidth;
DrawBlock(xstart, ystart, thiswidth, thisheight);
if (thiswidth==roomwidth) return;

xstart+=320;
thiswidth +=320;
if (roomwidth<thiswidth)thiswidth = roomwidth;
DrawBlock(xstart, ystart, thiswidth, thisheight);
if (thiswidth==roomwidth) return;

//repeat  this  if the room is any wider

}

function GrabHotspots() {

theroom = DynamicSprite.CreateFromBackground();
themask = theroom.GetDrawingSurface();


roomwidth=theroom.Width;
roomheight=theroom.Height;

// The next two operations mess up the game; Fix this later.
int hcount = 1;
while (hcount<50) {
hotspot[hcount].Enabled=true;
hcount++;
}

SetViewport(0, 0);

BlocksAcross(0);
if (roomheight>=240)BlocksAcross(240);
if (roomheight>=(240*2)) BlocksAcross(240*2);
// add lines if the room is any deeper

themask.Release();
theroom.SaveToFile("RoomHotspots.bmp");
theroom.Delete();
}
Title: Re: How do I fool the while loop iteration limit?
Post by: Ryan Timothy B on Fri 05/07/2013 00:19:54
This one is easy.  :-D

Code (ags) Select
function noloopcheck DrawBlock(int xfrom, int yfrom, int xto, int yto) {
  // etc
}

Or rather putting it on the function that exceeds 150k loops.
Title: Re: How do I fool the while loop iteration limit?
Post by: Hernald on Fri 05/07/2013 00:47:50
Spot on! Thanks Ryan!
If anyone's interested; here is the simplified code.
Code (AGS) Select

DynamicSprite* theroom;
DrawingSurface* themask;
Hotspot* hot;

function noloopcheck DrawHots(int xfrom, int yfrom, int xto, int yto) {
    int xcount;
    int ycount;
   
    xcount = xfrom;
    while (xcount<xto) {
        ycount = yfrom;
        while (ycount<yto) {
            hot = Hotspot.GetAtScreenXY(xcount, ycount);
// To-do: Fix drawing colours to shades of blue so its easy to convert to gif and re-import.
            themask.DrawingColor = hot.ID;
            themask.DrawPixel(xcount, ycount);
            ycount++;
        }
        xcount++;
    }
}


function GrabHotspots() {

    theroom = DynamicSprite.CreateFromBackground();
    themask = theroom.GetDrawingSurface();
 // To-do: Save hotspots.Enabled values and Viewport coordinates to restore later.  
    int hcount = 1;
    while (hcount<50) {
        hotspot[hcount].Enabled=true;
        hcount++;
    }
   
    SetViewport(0, 0);

    DrawHots(0, 0, theroom.Width, theroom.Height);
       
    themask.Release();
    theroom.SaveToFile("RoomHotspots.bmp");
    theroom.Delete();
}
Title: Re: SOLVED: How do I fool the while loop iteration limit?
Post by: Khris on Fri 05/07/2013 01:25:04
Are you using the hotspots bmp within the game?
Because if you just wanted to export the hotspots, you could also change the room background to all white and take a screenshot.
Title: Re: SOLVED: How do I fool the while loop iteration limit?
Post by: Hernald on Fri 05/07/2013 02:30:20
I'm after exporting the whole room, not just the visible screen after I have updated it in the AGS editor, so that I can convert it to a gif file and then reimport it if anything unfortunate happens to the in-game version.
My next challenge is getting up to forty-nine shades of blue (with no green).
Title: Re: SOLVED: How do I fool the while loop iteration limit?
Post by: Khris on Fri 05/07/2013 03:02:28
I'm talking about a screenshot of the editor, not an in-game one.
Unless you're using extremely large room graphics, you should be able to see the entire background in the editor if you set the zoom to 100%, right?
Turn down the transparency and you have all hotspots in varying shades of grey.
Title: Re: SOLVED: How do I fool the while loop iteration limit?
Post by: Hernald on Fri 05/07/2013 03:20:09
That's one option Khris, what I have done is add the magic number 65536 (from the TruBlu module) to the hotspot ID and it gives the map in shades of blue which I can port back into AGS when I need to, only having to change it to a gif.
The only downside of my method is that I need to call the function from the room in-game.

Here is the completed code:
Code (AGS) Select

DynamicSprite* theroom;
DrawingSurface* themask;
Hotspot* hot;

function noloopcheck DrawHots(int xfrom, int yfrom, int xto, int yto) {
    int xcount;
    int ycount;
   
    xcount = xfrom;
    while (xcount<xto) {
        ycount = yfrom;
        while (ycount<yto) {
            hot = Hotspot.GetAtScreenXY(xcount, ycount);
            if (hot.ID==0) themask.DrawingColor = 0;
            else {
                if (Room.ColorDepth==32) themask.DrawingColor = 65536+hot.ID;
                else {
                    if (hot.ID<32) themask.DrawingColor = 31+hot.ID;
                    else themask.DrawingColor = 224+hot.ID;
                }
            }
            themask.DrawPixel(xcount, ycount);
            ycount++;
        }
        xcount++;
    }
}


function GrabHotspots() {
  bool isenabled[50];
    int    xviewstore = GetViewportX();
    int yviewstore = GetViewportY();
    theroom = DynamicSprite.CreateFromBackground();
    themask = theroom.GetDrawingSurface();
   
    int hcount = 1;
    while (hcount<50) {
        isenabled[hcount]=hotspot[hcount].Enabled;
        hotspot[hcount].Enabled=true;
        hcount++;
    }
   
    SetViewport(0, 0);

    DrawHots(0, 0, theroom.Width, theroom.Height);

    hcount = 1;
    while (hcount<50) {
        hotspot[hcount].Enabled=isenabled[hcount];
        hcount++;
    }
   
    SetViewport(xviewstore, yviewstore);
   
    themask.Release();
    String filename;
    filename = String.Format("Room%dHotspots.bmp",player.Room);
    theroom.SaveToFile(filename);
    theroom.Delete();
}