Author Topic: MODULE: Magnifier v1.0 - What is that thing? Oh I see!  (Read 7236 times)

monkey0506

  • AGS Project Tracker Admins
  • Tasting the banhammer. Strangely, tastes like ham.
I actually stole the idea for this directly from Lego Indiana Jones. I was playing it and in Barnett College there's a map and you use a magnifying glass to indicate where you want to go next. As I was playing around with it the first thing that came to my mind was "somebody should write that module," so of course, I did.

So this module creates a magnifying glass-style effect for your game. I tested it with scale factors as high as 2.65 (265% scale) and as low as 0.1 (10% scale) and still maintained 40 FPS, though in rooms with other effects, lots of characters, etc. it may run quite slowly.

It requires a GUI to display the effect and a sprite to be used as the "magnifying glass." It does work with sprites with an alpha channel so you can for example create a light blue tint over the magnified area (as done by the included magnifier.png file). However if you have an alpha channel around the outer edge of the "frame" then it will display the magnified image behind the outer edge instead of the normal background. This is due to the way that AGS handles drawing alpha channels and should be corrected in a future version. Also the only real reason it requires a GUI is for future compatibility with that, but I could probably add an Overlay mode if requested.

Download
Mirror
User was banned for this post.

Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #1 on: 23 Oct 2009, 12:43 »
That would be a very useful module for me, because in my next game there will be a puzzle where you have to use a magnifier  :P
I'm glad that I found this, but unfortunatelly it's not working for me.
My room is 640x400, 32bit colour depth, and I've used your png file as the magnifier sprite, I've created a blank GUI and set everything as in the manual, but an error comes up at this line:

this.BackgroundSprite.CopyTransparencyM ask(sprite.Graphic);

The error message is:

DynamicSprite.CopyTransparencyMask: sprites are not the same colour depth.

What could be the problem?

Another question: what size should be the magnifier gui, and it should be blank or it should have a background?


monkey0506

  • AGS Project Tracker Admins
  • Tasting the banhammer. Strangely, tastes like ham.
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #2 on: 23 Oct 2009, 19:23 »
The DynamicSprite* for Magnifier.BackgroundSprite is assigned as:

Code: Adventure Game Studio
  1. this.BackgroundSprite = DynamicSprite.CreateFromBackground();

So a difference in the colour depth would mean that the room's background is not 32-bit...?

As far as the GUI goes the Width, Height, BackgroundGraphic, and Visible properties are all managed by the module's code so none of those are strictly relevant as far as the in-editor setup.

However what I'd suggest would be to just simply make it a transparent GUI the size of the magnifying glass sprite. That would probably be simplest. If it makes you feel better you could even assign its background graphic to that of the sprite. But any controls or other settings would not be affected, so could distort the effect...or you might be able to find a way to take advantage of these... ;)

Oh and I'm glad to hear that you'd find this useful. :)
« Last Edit: 23 Oct 2009, 19:26 by monkey_05_06 »
User was banned for this post.

Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #3 on: 23 Oct 2009, 21:58 »
It would be nice to see a picture of what one could expect from this without having to install it for themselves. :P
I only want to see what it does due to programing curiosity.
Sounds as though you're only enlarging a section of the background, so you're not seeing more, you're only seeing it enlarged.  Correct?

monkey0506

  • AGS Project Tracker Admins
  • Tasting the banhammer. Strangely, tastes like ham.
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #4 on: 24 Oct 2009, 05:11 »
Well it depends how much you can see prior to the scaling level being applied. :P

I'll try and get a screenshot up when I get the chance.

(What this module does is it resizes a portion of the background based on a given scaling level and then overlays a sprite on top of that, i.e. doing what a magnifying glass does. It won't actually allow you to see things that aren't already there, but it could be useful...maybe)
User was banned for this post.

Wonkyth

  • Liscence to Misspell.
    • I can help with AGS tutoring
    •  
    • I can help with making music
    •  
    • I can help with play testing
    •  
    • I can help with proof reading
    •  
    • I can help with scripting
    •  
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #5 on: 24 Oct 2009, 12:42 »
Couldn't you just have a second image that acts as the zoomed in version?
"But with a ninja on your face, you live longer!"

NsMn

  • HAIL CHAIRMAN MAIO, HAIL TO NINTENDISM!
    • I can help with AGS tutoring
    •  
    • I can help with backgrounds
    •  
    • I can help with play testing
    •  
    • I can help with proof reading
    •  
    • I can help with scripting
    •  
    • I can help with story design
    •  
    • I can help with translating
    •  
    • I can help with voice acting
    •  
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #6 on: 24 Oct 2009, 14:19 »
I have to agree, that would make it much easier.

Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #7 on: 24 Oct 2009, 14:44 »
Ok, it's working now :P
First I've imported a bigger background image then 640x400, so it's not working with scrolling rooms...
Here are two pictures showing the magnifier effect with 2x scale:

One more thing: when the player character is hidden, the magnifier shows him ;)
It's not a problem, because I can place him out of the screen, I just mentioned it :)

Wonkyth

  • Liscence to Misspell.
    • I can help with AGS tutoring
    •  
    • I can help with making music
    •  
    • I can help with play testing
    •  
    • I can help with proof reading
    •  
    • I can help with scripting
    •  
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #8 on: 25 Oct 2009, 02:51 »
On my earlier thought:
The only problem with that is that things that can move would need to be updated constantly, and for large rooms/high res games it's gonna use allot of space.
"But with a ninja on your face, you live longer!"

Knox

  • Storm Behind The Badge
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #9 on: 05 Apr 2011, 23:42 »
Hey Monkey,

1st, great module...Ive got it to work on my background no probs...super nice!

I was wondering, is there away to make this also work for magnifying gui's? Right now Im trying to magnify a gui, and the effect "cuts" through the gui and shows the background room instead.
--All that is necessary for evil to triumph is for good men to do nothing.

monkey0506

  • AGS Project Tracker Admins
  • Tasting the banhammer. Strangely, tastes like ham.
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #10 on: 06 Apr 2011, 02:59 »
Hey, I must have somehow missed a couple posts in this thread. Thanks to placyd for the bug reports and uploading those screenshots. I took a second to look over the code, and I'm pretty sure I know why it's not working with scrolling rooms. I have a couple projects I'm actively working on right now, but I'll try and keep this in mind that I need to fix this at some point. Hidden characters still showing up is pretty simple to fix also.

Regarding Wonky's suggestion of using a statically zoomed sprite, that's actually not a bad idea to allow the user to specify a separate static sprite this way (that would even allow you to show more detail, smooth scaling, etc.), and it also gave me the idea of caching the background sprite (instead of resizing a new dynamic sprite every game loop like it's doing now to get the background; characters and objects would still have to be dynamically added on top of that).

As for magnifying GUIs..I'm not sure. Because at that point I'd pretty much have to rerender the entire screen via the script, which would not be efficient at all. I'm already redrawing the background, characters, and objects..having to redraw GUIs and GUIControls (especially labels, textboxes, etc.) would make it somewhat of a nightmare.
User was banned for this post.

Knox

  • Storm Behind The Badge
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #11 on: 06 Apr 2011, 04:39 »
Suppose I just wanted to use it on gui's only (no redraw for backgrounds, characters, or objects)...would it be doable?

Ive got some gui's set up as booklets, and Id use the magnifier only on the gui area, to see small print, etc...it would never be used on the background room, characters or whatever...plus the game is paused so i was thinking is there a way to capture the whole screen, set it on the background, and then Id just hide all the open gui's...when the magnifier is closed, everything is restored to how it was.

I dont know, does that sound crazy? If so, crap! Got to rethink how Im gonna do this :P
--All that is necessary for evil to triumph is for good men to do nothing.

monkey0506

  • AGS Project Tracker Admins
  • Tasting the banhammer. Strangely, tastes like ham.
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #12 on: 06 Apr 2011, 07:26 »
I think that for your purposes the best thing to do would be to create a highly specialized route instead of a generic route. For that, let me ask you some questions..

Does your GUI move, or in any way change? Do the controls change? Is the text dynamic?

So long as the GUI stays in one place and doesn't change during magnification..it would be presumably possible to hide the mouse cursor, wait until the next game loop (for the screen to refresh), use DynamicSprite.CreateFromScreenshot to grab the image of the GUI, and then keep it as a cached copy..

Doing that would save you (or me :P) from having to redraw the GUI and its controls. This method wouldn't work well generically (or for other cases like the background, characters, and objects) because of the fact that if you use CreateFromScreenshot it will capture the mouse (even if you turn it off), so you have to wait till the next game loop.

The cached copy would be resized and cropped dynamically as needed..it could work well depending on your needs and implementation.
User was banned for this post.

Knox

  • Storm Behind The Badge
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #13 on: 06 Apr 2011, 18:11 »
Good news is that when I go into "magnify" mode...everything will be "frozen", as in the booklets can no longer be flipped. Nothing is dynamic at all.

Here is a screenshot to give an idea:



« Last Edit: 06 Apr 2011, 23:51 by General_Traitor »
--All that is necessary for evil to triumph is for good men to do nothing.

monkey0506

  • AGS Project Tracker Admins
  • Tasting the banhammer. Strangely, tastes like ham.
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #14 on: 06 Apr 2011, 21:16 »
Okay, I'm gonna take this to PM since this is going to be specialized code unrelated to the module.. ;)
User was banned for this post.

Knox

  • Storm Behind The Badge
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #15 on: 06 Apr 2011, 22:42 »
Ok Ill PM you  ;D
--All that is necessary for evil to triumph is for good men to do nothing.

Knox

  • Storm Behind The Badge
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #16 on: 01 May 2011, 20:21 »
Hey Monkey,

If you have a chance today (may 1st), go to Google homepage...there's a magnifier "effect" they are using whe you go over the google logo...which is pretty much like yours, no?

Kinda cool.
« Last Edit: 08 Jul 2011, 05:44 by General_Knox »
--All that is necessary for evil to triumph is for good men to do nothing.

Knox

  • Storm Behind The Badge
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #17 on: 08 Jul 2011, 05:44 »
MUaaaahhaahhh!!

Evil gril  ;D

...Now that you're on a roll with your modules Monkey...

<tilts head back and laughs maniacally while wringing hands>

...what says-you to p'raps make the above request work?   :-*

...MuuaAAhahaah-haha HAHA HAHAHh haha!!

<thunder claps in distance, evil glare in eyes>

Evil gril  ;D
--All that is necessary for evil to triumph is for good men to do nothing.

Knox

  • Storm Behind The Badge
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #18 on: 31 Aug 2011, 02:56 »
Quote
So long as the GUI stays in one place and doesn't change during magnification..it would be presumably possible to hide the mouse cursor, wait until the next game loop (for the screen to refresh), use DynamicSprite.CreateFromScreenshot to grab the image of the GUI, and then keep it as a cached copy..

Ok so once I get the screen grab, I can resize it/move it to follow the magnifier? I guess with an alpha channel on my magnifier sprite, I can "cut" that piece into a circle, right?

Im going to attempt to make the magnifier work on a static/non modifiable/non-moving GUI. :)
--All that is necessary for evil to triumph is for good men to do nothing.

Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #19 on: 28 Feb 2014, 13:35 »

Hi,

I'm working on an interactive-book about drawings and I really need a magnifying glass in order to allow the readers to magnify the drawings.
This module looks pretty good for my purpose but I couldn't use it so far... I don't know what's wrong :sad:

I followed the example written in the script's Header and I didn't get any error message, the magnifying glass sprite appeared but there's no zoom effect and actually the sprite covers the background.

Does anybody know why? I'm using the last AGS version (3.3.0). Can that be a possible reason? What should I do in this case?

Thank you
 

mitlark

  • I'm more of an RPG guy but I like AGS :V.
    • I can help with AGS tutoring
    •  
Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #20 on: 28 Feb 2014, 19:40 »
Does your magnifier sprite have alpha channel? If it does, then it should work. It it doesn't, by using an image editor make it have alpha, then make the center part semitransparent, AND make sure your background has alpha channel too.

If it throws an error saying something about color depth, modify your background, adding an alpha channel to it and making sure it is in 24bpp (or 32bpp if we count alpha). Then reimport the background.

Also, if it mentions something about sprites not being the same size (at least it threw me an error like that), add this line just before the one that the error remarks (possibly line 108):
Code: Adventure Game Studio
  1. sprite.ChangeCanvasSize(this.BackgroundSprite.Width, this.BackgroundSprite.Height, 0, 0);

I hope it works for you. I'm not going to use it, but this thing is pretty rad. Here a screenie:
Add spoiler tag for Hidden:
SPIN SPIN! SPIN SPIN!

Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #21 on: 01 Mar 2014, 09:46 »

The magnifier sprite had an alpha-channel (actually I used the sprite included by monkey in the module) but I never thought to change the backgrounds... then after your advices I saved the backgrounds as TIFF and reimported them. It was enough. Now everything works fine. Nice module!! :smiley:
Thanks for your answer

Re: MODULE: Magnifier v1.0 - What is that thing? Oh I see!
« Reply #22 on: 01 Dec 2017, 19:29 »
Okay... lets go for some necroposting (Hey I kind of asked)

Long story short: has anybody ever gotten this module to work with scrolling rooms?

If I have a scrolling room, aand I enable the magnifier - The picture behind the magnifier (which I think is the dynamic sprite from the background) will only show magnified whats in the first picture of the room, regarding my room resolution. So put simple: I walk right, the room scrolls, the magnifier acts as if the room would not scroll.
I know it's asked way to much of you to go trough all the Modules Code, if you don't have time/mood it's okay.

Here the vode basically

Code: Adventure Game Studio
  1.  
  2. void Update(this MagnifierType*) {
  3.   if ((this.AGSGUI == null) || (this.Sprite <= 0)) {
  4.     this.Enabled = false;
  5.     return;
  6.   }
  7.   if (this.prevenabled != this.Enabled) { // toggle on/off
  8.     if ((this.HideMouseCursor) || (this.prevhidemouse)) {
  9.       if (this.Enabled) this.HideCursor();
  10.       else this.ShowCursor();
  11.     }
  12.   }
  13.   else if ((this.prevhidemouse != this.HideMouseCursor) && (this.Enabled)) {
  14.     if (this.HideMouseCursor) this.HideCursor();
  15.     else this.ShowCursor();
  16.   }
  17.   this.prevhidemouse = this.HideMouseCursor;
  18.   if (this.ScaleFactor <= 0.0) this.ScaleFactor = 0.1;
  19.   this.prevenabled = this.Enabled;
  20.   this.AGSGUI.Visible = false;
  21.   if (!this.Enabled) return;
  22.   this.AGSGUI.BackgroundGraphic = 0;
  23.   this.X = mouse.x;
  24.   this.Y = mouse.y;
  25.   if ((this.X + this.XOffset) < 0) this.AGSGUI.X = 0;
  26.   else if ((this.X + this.XOffset) >= System.ViewportWidth) this.AGSGUI.X = (System.ViewportWidth - 1);
  27.   else this.AGSGUI.X = (this.X + this.XOffset);
  28.   if ((this.Y + this.YOffset) < 0) this.AGSGUI.Y = 0;
  29.   else if ((this.Y + this.YOffset) >= System.ViewportHeight) this.AGSGUI.Y = (System.ViewportHeight - 1);
  30.   else this.AGSGUI.Y = (this.Y + this.YOffset);
  31.   DynamicSprite *sprite = DynamicSprite.CreateFromExistingSprite(this.Sprite, false);
  32.   int x = (FloatToInt(IntToFloat(this.X) * this.ScaleFactor) + this.XOffset);
  33.   int y = (FloatToInt(IntToFloat(this.Y) * this.ScaleFactor) + this.YOffset);
  34.   sprite.ChangeCanvasSize(FloatToInt(IntToFloat(System.ViewportWidth) * this.ScaleFactor), FloatToInt(IntToFloat(System.ViewportHeight) * this.ScaleFactor), x, y);
  35.   this.BackgroundSprite = DynamicSprite.CreateFromBackground();
  36.   DrawingSurface *surface = this.BackgroundSprite.GetDrawingSurface();
  37.   int i = 0;
  38.   while ((i < Game.CharacterCount) || (i < Room.ObjectCount)) {
  39.     if (i < Game.CharacterCount) {
  40.       if (character[i].Room == player.Room) {
  41.         ViewFrame *frame = Game.GetViewFrame(player.View, player.Loop, player.Frame);
  42.         int w = ((Game.SpriteWidth[frame.Graphic] * character[i].Scaling) / 100);
  43.         int h = ((Game.SpriteHeight[frame.Graphic] * character[i].Scaling) / 100);
  44.         surface.DrawImage(character[i].x - (w / 2), character[i].y - h, frame.Graphic, 0, w, h);
  45.       }
  46.     }
  47.     if (i < Room.ObjectCount) {
  48.       if (object[i].Visible) {
  49.         int graphic = object[i].Graphic;
  50.         if (object[i].View) {
  51.           ViewFrame *frame = Game.GetViewFrame(object[i].View, object[i].Loop, object[i].Frame);
  52.           graphic = frame.Graphic;
  53.         }
  54.         int w = Game.SpriteWidth[graphic];
  55.         int h = Game.SpriteHeight[graphic];
  56.         if (!object[i].IgnoreScaling) {
  57.           int scale = GetScalingAt(object[i].X, object[i].Y);
  58.           w = ((w * scale) / 100);
  59.           h = ((h * scale) / 100);
  60.         }
  61.         surface.DrawImage(object[i].X, object[i].Y - Game.SpriteHeight[graphic], graphic);
  62.       }
  63.     }
  64.     i++;
  65.   }
  66.   surface.Release();
  67.   this.BackgroundSprite.Resize(FloatToInt(IntToFloat(this.BackgroundSprite.Width) * this.ScaleFactor), FloatToInt(IntToFloat(this.BackgroundSprite.Height) * this.ScaleFactor));
  68.   sprite.ChangeCanvasSize(this.BackgroundSprite.Width, this.BackgroundSprite.Height, 0, 0);
  69.   this.BackgroundSprite.CopyTransparencyMask(sprite.Graphic);
  70.   int w = Game.SpriteWidth[this.Sprite];
  71.   int h = Game.SpriteHeight[this.Sprite];
  72.   int ww = this.BackgroundSprite.Width;
  73.   int hh = this.BackgroundSprite.Height;
  74.   if ((ww > w) && (hh > h)) this.BackgroundSprite.Crop(x, y, w, h);
  75.   else if (ww > w) {
  76.     this.BackgroundSprite.Crop(x, 0, w, hh);
  77.     if (hh < h) this.BackgroundSprite.ChangeCanvasSize(w, h, 0, (h - hh) / 2);
  78.   }
  79.   else if (hh > h) {
  80.     this.BackgroundSprite.Crop(0, y, ww, h);
  81.     if (ww < w) this.BackgroundSprite.ChangeCanvasSize(w, h, (w - ww) / 2, 0);
  82.   }
  83.   else this.BackgroundSprite.ChangeCanvasSize(w, h, (w - ww) / 2, (h - hh) / 2);
  84.   if ((ww <= w) || (hh <= h)) {
  85.     sprite = this.BackgroundSprite;
  86.     this.BackgroundSprite = DynamicSprite.Create(w, h, false);
  87.     surface = this.BackgroundSprite.GetDrawingSurface();
  88.     surface.Clear(0);
  89.     surface.DrawImage(0, 0, sprite.Graphic);
  90.     surface.Release();
  91.   }
  92.   surface = this.BackgroundSprite.GetDrawingSurface();
  93.   if (this.ScaleFactor < 1.0) {
  94.     surface.DrawingColor = 0;
  95.     int xm = FloatToInt(IntToFloat(System.ViewportWidth) * this.ScaleFactor);
  96.     int xx = (x + w);
  97.     if (x < 0) surface.DrawRectangle(0, 0, -x, surface.Height);
  98.     if (xx >= xm) surface.DrawRectangle(xm - x, 0, xx - x, surface.Height);
  99.     int ym = FloatToInt(IntToFloat(System.ViewportHeight) * this.ScaleFactor);
  100.     int yy = (y + h);
  101.     if (y < 0) surface.DrawRectangle(0, 0, surface.Width, -y);
  102.     if (yy >= ym) surface.DrawRectangle(0, ym - y, surface.Width, yy - y);
  103.     if ((x < 0) || (y < 0) || (xx >= xm) || (yy >= ym)) {
  104.       surface.Release();
  105.       sprite = DynamicSprite.CreateFromExistingSprite(this.Sprite, false);
  106.       this.BackgroundSprite.CopyTransparencyMask(sprite.Graphic);
  107.       surface = this.BackgroundSprite.GetDrawingSurface();
  108.     }
  109.   }
  110.   surface.DrawImage(0, 0, this.Sprite);
  111.   surface.Release();
  112.   x = (this.X + this.XOffset);
  113.   y = (this.Y + this.YOffset);
  114.   int xx = (x + w);
  115.   int yy = (y + h);
  116.   if ((xx <= 0) || (yy <= 0) || (x >= System.ViewportWidth) || (y >= System.ViewportHeight)) {
  117.     this.BackgroundSprite = null;
  118.     this.AGSGUI.BackgroundGraphic = 0;
  119.     this.AGSGUI.Width = 1;
  120.     this.AGSGUI.Height = 1;
  121.   }
  122.   else {
  123.     if ((x < 0) && (y < 0)) this.BackgroundSprite.Crop(-x, -y, this.BackgroundSprite.Width + x, this.BackgroundSprite.Height + y);
  124.     else if (x < 0) this.BackgroundSprite.Crop(-x, 0, this.BackgroundSprite.Width + x, this.BackgroundSprite.Height);
  125.     else if (y < 0) this.BackgroundSprite.Crop(0, -y, this.BackgroundSprite.Width, this.BackgroundSprite.Height + y);
  126.     this.AGSGUI.BackgroundGraphic = this.BackgroundSprite.Graphic;
  127.     this.AGSGUI.Width = this.BackgroundSprite.Width;
  128.     this.AGSGUI.Height = this.BackgroundSprite.Height;
  129.   }
  130.   this.AGSGUI.Visible = true;
  131. }
  132.  
  133.