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?
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();
}
This one is easy. :-D
function noloopcheck DrawBlock(int xfrom, int yfrom, int xto, int yto) {
// etc
}
Or rather putting it on the function that exceeds 150k loops.
Spot on! Thanks Ryan!
If anyone's interested; here is the simplified code.
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();
}
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.
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).
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.
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:
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();
}