[Solved] Screen size issue on the PC...

So my client… Laine Gabriel has been contacting you about trying to get a SWF working with iScreensaver for which they have/purchased.

I do not own the software myself as I am just a developer contracted to make the SWF. I am very familiar with designing software for liquid layouts and very fluent with ActionScript and OOP practices. However this situation has been an ankle biting problem.

For one, I am not even sure what the issue is… apparently they get a blank screen with no error being thrown or warning or anything on their PCs. Though I have never seen this myself as I do not own a PC. I have only read descriptions from the client.

I am attaching the source files without any of the changes you had me make to avoid any confusion:
[ private URL redacted ]

This screensaver isn’t as easy as just making a timeline, although a significant portion does contain a timeline, the requirements are that the stage resizes to fit any screen and the Date class is used to dynamically query the system time to display a countdown.

The main ‘Application’ class is the SWF’s document class. It has an event listener for Event.RESIZE and I adjust the scale of the side bars and main animation to fit any size screen. The only other thing it does is set up stage.align=StageAlign.TOP_LEFT; and stage.scaleMode=StageScaleMode.NO_SCALE; in the constructor.

Everything works as it should across every Flash player I test, except yours. To me it sounds like stage.stageWidth and stage.stageHeight is always reporting 0… which would make the resize scale down to 0 as well. This sounds like a bug with your Flash player. Any chance you got a buggy embedded player from Adobe? Or are you distributing this in some other method… like relying on the system’s Flash player?

Either way, the first thing I would try is applying a setTimeout(onResize,500); inside that constructor to wait for a period of time before calling onResize(). That would be the simplest way to ensure iScreensaver is ready before it sets its final resize.

I am not sure about how any of those other suggestions would help… Although we did try them, they seem very strange to me. Especially having one frame after the stop()… that just sounds crazy! Let me know if you can get anything up and running on your side. I am going to try some other software to see if it is iScreensaver causing the issue. If you can get it to work, we would like to know what you fixed! Thanks!

I will report back to you if I find anything. Thanks!

Thanks, EG - I’m looking at your files right now.

Ok, I believe I’ve solved it.

There are two issues:

First, your Application actionscript code is attempting to do a resize via right when it starts up - this is too soon, and (as we’ve suspected) the stage.stageWidth and stage.stageHeight both equal zero. The solution is to put the resize on a timer, as shown below.

The second issue was more subtle - I had a look inside your Animation.as code, and it looks as if you’ve hard-coded your stage size:

private var initWidth:int=1366;
private var initHeight:int=768;

You then use those values to calculate the new size and aspect ratios of some objects. This is not a bad technique in general, however, the way iScreensaver works is that it plays back in a context where SCALE=EXACTFIT. It turns out that in this context, Flash player does some weird things with animation coordinates (this may be a bug in Flash player, I’m not 100% sure).

The solution is fairly simple:

  1. Set your stage to StageScaleMode.EXACT_FIT

  2. Do your resizing on a timer.

  3. In your resizing methods, when you are calculating sizes of objectsDon’t hard-code screen coordinates : instead, read the stage width and height at runtime, e.g.
    initWidth:int=stage.stageWidth;
    initHeight:int=stage.stageHeight;

  4. Finally, make sure you have the iScreensaver Stretch mode set to “FILL” - with all three of these things set properly, it should work fine.

Code examples follow:

package
{

import flash.display.*;
import flash.events.*;
import flash.utils.*;

public class Application extends MovieClip
{
	var myTimer:Timer;
	public var sidebar1:SideBar;
	public var sidebar2:SideBar;
	public var sidebar3:SideBar;
	public function Application()
	{
		stage.align = StageAlign.TOP_LEFT;
		stage.scaleMode = StageScaleMode.EXACT_FIT;
		sidebar1.mouseEnabled = sidebar2.mouseEnabled = sidebar3.mouseEnabled = animation.mouseEnabled = sidebar1.mouseChildren = sidebar2.mouseChildren = sidebar3.mouseChildren = animation.mouseChildren = false;
		stage.addEventListener(Event.RESIZE,onResize);
		onResize();
	}
	private function timerResizeCallback(evt:TimerEvent):void
	{
		// now that the stage is ready, do the actual resizing
		trace("resizeCallback stage.stageWidth=" + stage.stageWidth + " x " + stage.stageHeight + " Doing Resize Now");
		trace("resizeCallback stage.width=: " + stage.width + " x " + stage.height );
		myTimer.stop();
		myTimer = null;
		
		// authors: do your custom resizing here...
		animation.setSize(stage.stageWidth,stage.stageHeight);
		sidebar1.height = sidebar2.height = sidebar3.height = stage.stageHeight;
		sidebar1.scaleX = sidebar2.scaleX = sidebar3.scaleX = sidebar1.scaleY;
	}
	private function onResize(e:Event=null):void
	{
		trace("OnResize stage.stageWidth=" + stage.stageWidth + " x " + stage.stageHeight + " Launching Timer");
		trace("OnResize stage.width=: " + stage.width + " x " + stage.height );
		if (! myTimer)
		{
			// set up a one-shot 500msec timer which will do the actual resizing
			myTimer = new Timer(500,0);
			myTimer.addEventListener(TimerEvent.TIMER, timerResizeCallback);
			myTimer.start();
		}
	}
}

}

Note: I see that you do some custom resizing in your SideBar.as file : I’m not sure how that works, but it’s clear that the sizing comes out wrong, you’ll probably need to fix that using the same technique (base the sidebar size and scale aspect ratio on the current stage size, not the size you designed for).

Well, I’m not exactly sure that totally solves it. EXACT_FIT stretches to fill the screen, but the problem with that is that it will distort the images based on which aspect ratio you are using. My resize code was actively resizing and reposition content based screen size and aspect ratio.

I will provide the client with a version of the files you created, but I may have to also provide an alternative that accurately resizes to any screen dimension instead of just stretching it.

Also, if iScreensaver is using EXACT_FIT, it could explain why so many are having issues aligning things to the stage.

If a SWF is set to EXACT_FIT, the resize event is not fired. So that would explain why the resize method was not firing in our case. In fact, setting it to EXACT_FIT effectively disables any resizing and just stretches the stage to fit the screen. So that’s why it “appeared” to work.

Can iScreensaver use any other resize method?

Yes, iScreensaver has built-in support for a bunch of resizing modes, including FILL (the one that you chose), CROP, LETTERBOX, etc. Your file was designed using FILL so that’s what I assumed that you wanted. If you are OK with content going off the edges, then choose CROP. If you prefer black bars, then choose LETTERBOX.

But I think this is kind of missing the point: the SWF file you authored is a good one, as it implements something more sophisticated than just a plain stretch. That’s good, and is the right way to do things when you want to have various parts that all each stretch and scale independently

The problem was that these files were not authored properly to handle the EXACT_FIT mode, which is what iScreensaver uses when you choose to have the content fill the full-screen area. Some of the code I looked at had hard-coded screen resolutions, which is what was messing up the calculations.

From what I saw, you only needed to fix one more file, and it’d be perfect.

If you don’t have time, then the original file you sent us seemed to work fine in LETTERBOX mode without any changes.

But it’s a really nice looking animation, so I’m hoping you can get it working in FILL mode too.

You said “My resize code was actively resizing and reposition content based screen size and aspect ratio.” and this is true : the code just needs to be tweaked a little to handle the EXACT_FIT.

AHH! I think I get what is going on here!

You see, I have never even used iScreensaver. I handed my SWFs off to the client to implement. Maybe they chose the wrong scale mode for my SWF?

I am at a disadvantage as I don’t have a PC to test on… nor do I own this software or have used it before. I am installing the Mac version to become more aware of what the client is seeing.

If I seem to get things working on my end would you mind trying it out?

Thanks for all the help you have been spectacular!

No problem, this has been a difficult but rewarding puzzle!

I think the only thing that wasn’t quite right in your resizing code was the use of the original screen size (1366x768) in your calculations - as I understand it, the weird thing about EXACT_FIT mode is that Flash player basically lies to your SWF file about what the actual stage size is. For example, if you want to have a 100x100 pixel box, in EXACT_FIT mode, Flash player may stretch that out to a different size behind your back.

For the future, we may be able to add an override feature to iScreensaver so that you could choose a different scale mode (perhaps NO_SCALE would be a good alternative?) I don’t think that would necessarily make things better, but having more options is usually good for expert SWF programmers users like yourself.

Also, if you need to debug your code, this technique can help: http://iscreensaver.com/forum/discussion/160/iscreensaver-flash-player-debug-logging-using-trace-and-mm.cfg

NO_SCALE would definitely solve many of these problems I think. If you could add that in the future it would likely make many developers very happy!

For many Flash developers, we are very accustomed to setting it to NO_SCALE and TOP_LEFT in nearly every application we develop.

It’s usually the inexperienced Flash designers that rely on other scale modes for simplicity sake. I understand those designers are probably a pretty sizable market for your company. But us developers cringe at the thought of not controlling it ourselves.

If a developer wants granular control over the display of these swfs, NO_SCALE is the most faithful.

So I think I may have gotten somewhere… At least it looks great on the mac…

Can you try it on a PC for me before I hand of to the client?
https://dl.dropbox.com/u/1256960/Freelance/Nationwide_Screensaver/Screensavers.zip

I think the key might be the following settings:
https://dl.dropbox.com/u/1256960/Freelance/Nationwide_Screensaver/IScreensaverSettings.png

I am thinking Custom scale is the same as NO_SCALE… so it might be the trick we need.

  • Your suggestion about allowing NO_SCALE is a good one, we’ll take it into consideration.

  • As for CUSTOM: unfortunately when you choose a CUSTOM scale size in iScreensaver, it uses EXACT_FIT, always.

  • The demo you sent looks great on Mac, but is still misbehaving on Windows PCs - the content is resizing to the top/left of the screen and not filling out the whole screen.

Bummer!!! It looks great in preview mode and when I install it. There has got to be some bug with the PC player.

And yes… PLEASE take NO_SCALE into consideration as this is quite the headache!

I will try some more things thanks for trying it out!

Here’s what it looks like:
http:/iscreensaver.com/forum/pix/NationwideScreenshot.png

What happens when you install the screensaver?

Previewing full screen on PC, or installing and Running it : same result - the content is squished to the left.

I’m pretty sure I fixed that bug in the Animation.as and Application.as files I sent back to you - are you sure that you incorporated my changes? It kind of looks like you might not have done so?

I was getting squished content when I used those settings. I am trying something else that will counteract EXACT_FIT to force it to act as if it were NO_SCALE. I will post what I find. Thanks!

By George, I think I’ve got it:

The problem was this line in your Application.as file:

sidebar1.scaleX = sidebar2.scaleX = sidebar3.scaleX = sidebar1.scaleY;

Normally, this works great, bit when running under EXACT_FIT mode, it has the wrong scaling.

The solution is to just use the same scaling algorithm that you’ve got in place for your “animation” object:

sidebar1.scaleX = sidebar2.scaleX = sidebar3.scaleX = animation.scaleX
sidebar1.scaleY = sidebar2.scaleY = sidebar3.scaleY = animation.scaleY

I’ll email you my revisions, which I’ve tested on PC and seem to look fine.