EDIT 2: swfmill has actually been updated for the first time in about 3 years (wav support included)! An official Windows binary and source code available here. If you’re a Windows user you can skip the stuff about compiling swfmill.

EDIT: Windows swfmill that (apparently) supports wav files available here (thanks rideforever). Just skip straight to working with swfml if you’re using these builds.

Why mxmlc can’t import wav (or any other lossless audio format) files I will never know. Mp3s suffer from timing/looping issues that are easily resolved by using wav files so I’ve always found a way to get my wav files into my swfs. Usually it’s by using the Flash IDE, but I refuse to involve it in my development process anymore.

Other solutions involve parsing wav files, generating swfs on-the-fly, or using Flash 10’s sound api. None really satisfied what I was looking for, compiling them directly into my AS3 code.

I’ve recently discovered a very good solution. It involves compiling a custom version of swfmill with support for wav files then using it to generate swf files. Since any resource inside a swf can be embedded into other swf files using mxmlc, I can then actually import a wav file.

Compiling swfmill

EDIT 2: Like I mentioned above, if you’re a Windows user you can skip this section. Also, if your favorite package manager has swfmill 0.3.0, you can just use that version instead.

This process is intended for Ubuntu, but it’s probably similar to the OSX version if you do the some extra research yourself. As for Windows, you’re on your own, unless you find a way to do it with cygwin.

First, make sure necessary build tools and libraries are available to compile swfmill. On Ubuntu these will do the trick (I think, be sure to comment if you find something is missing):

$ sudo apt-get install build-essential
$ sudo apt-get build-dep swfmill

Next, download the fork of swfmill located here. There’s a download link above the description. It’s a little more advanced than the version available on swfmill.org, in paticular it has support for wav files. Use the latest version of swfmill available here. The lastest version of swfmill will do the trick now. Get it here. Extract it to a folder and compile it.

$ ./autogen.sh
$ make

If anything goes wrong you might be missing some libraries or tools. Use this new new swfmill binary (it’s in the src folder) to compile the upcoming swfml files. Now you can create swf files with wav files in them, but they’re not in your main swf yet.

Using swfmill

This sample swfml file will create a swf file with a single wav file embedded inside (I personally recommend only having one wav file per swf file). Not all wav files will work. only PCM wav files with a frequency of 44100 Hz and below are allowed. Replace “wav_file_to_import” with the location of your wav file and compile.

$ swfmill simple examplesound.swfml examplesound.swf

As an added bonus, it will also play the wav file if you open the swf. Now you can embed the wav file in this swf into your main swf using the embed tag.

[Embed(source='examplesound.swf#importedsound')]
static private const ExampleSound:Class;

public function playSound():void {
  var sound:Sound = new ExampleSound() as Sound;
  sound.play(0, 1);
}

Hope that helps somebody, it’s been a thorn in my side for a long time.

A Nifty AS3 State Trick

January 1st, 2009

I was working on an AS3 class that had a state that needed to be reset every once and a while to some arbitrary original state. It turned out to be an interesting problem. The easy solution of course, is to store the original values into secondary properties and use these values to restore the original state.

public class Example {
  private var _originalX:Number;
  private var _originalY:Number;
  private var _x:Number;
  private var _y:Number;
  public function Example(x:Number, y:Number) {
    _originalX = x;
    _originalY = y;
    reset();
  }
  private function reset():void {
    _x = _originalX;
    _y = _originalY;
  }
  public function doSomething():void {
    reset();
  }
}

Since I was going to do this whole state thing for more classes, and because I felt there had to be an easier way, I went looking for a better solution.

First I thought I could write a function that stored all the properties when called, so it could restore them later. This couldn’t work because not all the properties should be reset. I considered adding a list of properties that should be stored (or not stored), so it would only reset the values I choose.

This solution still seemed imperfect, since creating a large list of state properties was just as annoying as the easy solution, and offered no compiler errors if I made any mistakes. In addition it wouldn’t work for more complex situations like this one.

public class Example extends State {
  private var _rect:Rectangle;
  private var _speed:Number;
  public function Example(rect:Rectangle, speed:Number) {
    _rect = rect;
    _speed = speed;
    // The properties of _rect will not be stored, just the _rect itself
    store("_rect", "_speed");
  }
  public function doSomething():void {
    reset();
    // _rect is unchanged
  }
}

My ideal solution seems so obvious now. It can handle more complex state details, offers nice compiler errors when I make a mistake, and only adds about four extra lines of code to the whole class. Simply use an anonymous function in the constructor as a way of storing the original state so it can be called again later.

public class Example {
  private var _speed:Number;
  private var _rect:Rectangle;
  private var reset:Function;
  public function Example(rect:Rectangle, speed:Number) {
    reset = function():void {
      _rect = rect.clone();// I'm assuming that the original rect doesn't change here
      _speed = speed;
    }
    reset();
  }
  public function doSomething():void {
    reset();
  }
}

I can’t think of many flaws, its main problem is that it does not play well with OOP, since the function must be anonymous and cannot be overridden. Subclasses can still implement this it independently or work together, it’s just not OO by default. It’s probably not going to save any extra memory either, but I wasn’t paticularly concerned about that.

Also, I think it’s important to avoid using the “this” keyword in the anonymous function (or any anonymous function for that matter) since what “this” is can change. For reasons unknown to me, properties accessed without using “this” (like in the example above) always reference the original. Calls however, do not appear to do this.

This could be considered more trouble than its worth, but it didn’t just simplify my code, it turned out to be invaluable as a way to manage the state of the classes I was working with later.

Listen, I know that cool animation on your website looks great. I know! I think it looks pretty alright too. After all we both probably use Firefox on some fast computers, right? Lots of popular sites use animation! Well, I’m here to try and convince you that you are so very very wrong. One of the greatest sins to commit in Javascript is to add in an animation library.

Please stop imposing your will on the people unfortunate enough to suffer slow computers. You’re running a website, not Crysis, it should run on a 5-year-old computer. When I head home for the holidays animation suddenly becomes a curse. I watch, in horror, as your finely tuned and tweened animation moves jerkily across the screen of my mom’s computer. Since it runs too often because it is not expecting my computer to be slow, your animation freezes up my browser, and due to the single-threaded nature of this Pentium 4 computer, the entire OS as well. I sit there, locked into viewing your horrorshow animation, unable to do anything but cry.

The road to hell is paved with good intentions. Here’s a play-by-play.

  • You may decide to set up each animation frame is a setInterval call. After all, setInterval should call this function every 30 ms if I tell it to, right?
  • Discovering that the time between setInterval calls has no correlation to reality since browsers both clamp the speed and ignore it due to the nature of Javascript. So instead, one may base the animation on actual time, rather than frames, probably using Date.
  • Later, you may notice it looks terrible on older computers. Turns out that alpha-blending the entire screen was too much for them. You realize that the same effect works better on a smaller area since browsers tend to only update the area that has changed.
  • Nonetheless, you may notice it runs too slow on older computers. Realizing that setInterval is basically running constantly, you have it run less constantly. Now your animation is choppy on fast computers.
  • You start building a speed-detecting system before you realize it probably won’t work right and you are going insane and adding all this code to what amounts to a minor visual effect is silly.

I know animation is awesome, but Javascript is just not a platform that wants to deal with it. HTML may be a standard but browser performance isn’t. Remember that the goal of a browser is to protect users from the mistakes of foolish/malicious developers, something that your animation is doing to my old computer. To this end all browsers clamp the speeds of setTimeout/setInterval, but it doesn’t work for everybody. Smart developers should know that and avoid animation in Javascript almost entirely.

That being said, the title of this post is a lie. I think animation should be experimented with, but the only decent animation I’ve seen on websites is the subtle kind. Javascript/HTML, of all the platforms with the potential for animation, is one of the least capable of doing it right. Just keep that in mind and I won’t complain anymore, okay Internet?

OC ReMix Legitimized

November 28th, 2008

So, maybe you’ve heard of the longest named Street Fighter game ever (but what with there being so many out there, who among us can really know?) known as Super Street Fighter II Turbo HD Remix. I was surprised to learn that OC Remix, who’s artists have repeatedly allowed me to include their music in my games, handled the soundtrack. It’s even free to download. This impressive feat of fan-service demands to be linked to.

Doom Plays Flash

November 28th, 2008

So, before I could blink, somebody at Newgrounds put together a source port of Doom using Alchemy. Ah well, I was too slow. Through various means I’ve obtained the source code to this port. Mike Welsh, the fellow who created is working on properly releasing the source code. its understandable I suppose, he really did throw it together.

Nonetheless under the powers of the GPL I am providing the thrown together version here if you want it. I haven’t personally compiled it, so you can investigate yourself or wait for Mike’s official version. Good job Mike.

Flash, C/C++ and LLVM

November 18th, 2008

The most interesting thing Adobe has recently announced at Adobe MAX is (easily) Alchemy. It adds some modest support for C/C++ in Flash, but this is still nothing compared to how they did it. Tucked away in the Alchemy FAQ it mentions they used LLVM to do the job. It works by compiling C/C++ to the LLVM instruction set and then converting that to Flash bytecode.

LLVM is intended to act as a medium between a language and an instruction set. If you write a language that compiles to LLVM instructions, you automatically support any instruction set that LLVM supports. If you write a back-end that can understand/convert LLVM instructions, you support any language that compiles to LLVM instructions.

So basically, Adobe may have just opened the door for Python, Java, CIL/.NET languages, and others. I doubt they work right now (I haven’t had the opportunity to try Alchemy yet), and support for Flash’s API would be missing of course, but it appears to be coming.

Update: My guide here is quickly becoming outdated. See what Ben has to say in the comment section.

I really love Opera. It was one of the pieces of software I felt bad about leaving behind during my switch to Linux. Unfortunately on Linux it ran much slower and looked awful, me being a Gnome/GTK kind of guy, and Opera using Qt3.

Well, Opera seems to have gotten some speed boosts lately, plus there’s this project called qgtkstyle which makes Qt4 applications look like GTK applications. I figured out how to combine all this to make Opera integrate pretty well with the visual style I’m using. Here’s how I pulled it off.

Install checkinstall.

$ sudo apt-get install checkinstall

Install qgtkstyle.

See this guide for any details on packages you may need to compile the source.

$ mkdir qgtkstyle-0.1~custom
$ cd qgtkstyle-0.1~custom
$ svn co svn://labs.trolltech.com/svn/styles/gtkstyle .
$ qmake && make
$ sudo checkinstall make install

Install Opera 9.60 Beta (Snapshot 2436).

The only apparent version of Opera that uses shared libraries, rather than statically-linked versions is available here. Download this version. It’s a beta of 9.60 (9.62 being the most current version as of this writing), but I haven’t really had any problems with it

Some visual improvements.

Start Opera. The titlebar should look like a GTK toolbar. Go to Tools->Appearance->Skin, change the color scheme to “System color scheme”. You can try changing the skin to “Qt Native”, but I think it looks awful, so I’m sticking with Opera’s standard theme. Finally, go to Tools->Preferences->Web Pages, and change the normal font to a more reasonable size (14 looks pretty nice on my computer). Do the same for the monospace font, and you’re done!

This is ultimately a hack, just out there for the impatient like me. Hopefully the Opera people will figure out whatever problem is causing them not to used shared libraries with Qt, and hopefully they’ll do it around the time next version of Qt arrives that includes qgtkstyle, making all of this obsolete.

typeface.js

October 28th, 2008

Embedding fonts in web pages is tricky business. I never really liked the (and let’s face it) hack that has Flash do this job, since Flash can embed fonts. It’s always a little imperfect, since Flash never really integrates fully with web browsers. There’s a CSS way to do it, but apparently it’s spotty.

Hulu is the most popular website I’ve seen use the Flash technique. They use it for the titles of videos since apparently no standard font is capable of displaying it to their needs. Problem is, when you dim the screen, The title of the video doesn’t dim with the rest of the page (at least when I’ve used it). And despite some good effort, it’s basically impossible to highlight Flash and non-Flash text together.

But no more! Now there is typeface.js. It uses canvas (and VML apparently in IE) to draw the fonts directly. Since it’s the browser doing the work in integrates much better into the structure of an HTML document. You can actually highlight the text! Well, not in IE, but I’m betting those users don’t care. And it all fails very gracefully.

I own a PS3, there I said it

October 21st, 2008

So I bought a PS3. How scandalous! I am now a lost soul to some, they shake their heads sadly as they imagine me, PS3 controller in hand, numbly pushing buttons not realizing that the PS3 isn’t even on. I too was convinced the PS3 was to be relegated to a modest 3rd place effort, while the Wii and 360 would rule all.

Let’s get some things straight. The Wii is a failure to the average gamer. Everybody knocks the Gamecube but even in third place, it kept me happy as I purchased over two dozen games for the damn thing, some of which included the greatest games made during the entire generation. The Wii is a far worse example of all the things people complained about during the Gamecube era, the only difference is gamers want the Wii to succeed, and they wanted the Gamecube to fail. Meanwhile, I can tell you for a fact, those motion detectors barely detect motion.

But still, why an extra $150-$50 for a such a shameful choice in this generation’s console wars? Well, it came with a game, plus I don’t have to play for it’s (inferior) Xbox Live, and the thing really is very well refined so the extra cost didn’t really seem like much. It actually has more games I want to play. Many of the better games out there for the 360 also come for the PS3, and I don’t really want to play Microsoft-sponsered FPS #10 when I personally think Call of Duty 4 is all I need for now. Despite that, the real deal breaker is when you consider that I owned a Gamecube, remember? No PS2, or PS1 for that matter. With PS2 games at rock bottom prices used, I’m spending my time with an entire library I skipped over while everybody waits for the Wii to start being whatever it is they want it to be.

Dynamic sound? Meh. 3D? Yawn. Keyboard support in fullscreen mode? Now we’re talking.

You can only use Tab, Space, and the arrow keys though. Tab for jump, space for fire? At least it’s something.