Older blog entries for pabs (starting at number 32)

EasingJS, a JavaScript Easing Library

I just released EasingJS 0.1.1, a port Robert Penner's ActionScript Easing library to JavaScript. EasingJS allows you to easily generate smooth and stylish animation or color transitions. For some examples, check out the test page.

Syndicated 2008-05-14 22:25:49 from Pablotron: News

Custom Firmware on the PSP

Last night I installed a custom firmware (CFW) on my PSP. The custom firmwares allow you to run unsigned homebrew (e.g. non-Sony sanctioned) applications.


The PSP homebrew community has been pretty active; there are several useful applications and emulators for lots of older systems. There are even emulators for obscure systems like the ColecoVision and Neo Geo.

Here's what works for me so far, in no particular order:

I also tried the Genesis, NES, and N64 emulators, but they aren't working yet. Here's a picture of the SNES emulator at work:

Playing SNES on a PSP
Playing SNES on a PSP

The custom firmware also allows you to dump UMDs and run them from a memory stick. Since it's pretty much impossible to fit a PSP and 8 UMDs in the your pockets without looking like a complete tool, I'm going to offload as many UMDs as I can into the 3GB remaining on my memory stick.

The next section explains the firmware installation process. If you don't have a PSP, you may still find my creatively ominous safety warnings entertaining.


Installing the custom firmware varies in complexity depending on the model of PSP model and version of the original firmware. If you're fortunate enough to have an older "phat" PSP (e.g. the larger black model) that's running firmware 1.00 or 1.50, then installing the custom firmware is fairly straightforward.

If you know someone with a PSP who already has the custom firmware installed, then the installation process is still easy enough, because they can use their PSP to help you with yours.

If you've got a newer PSP Slim (the smaller white model, like the one in the picture above) and/or are running a newer firmware, then there are no easy options left, so get ready for the comically unpleasant experience below.

In order to install the custom firmware, you'll need a spare battery and a spare memory stick. For the love of Douglas Adams, please do not use this post as a guide! There are several web sites (here and here) that cover the entire installation process in far more detail and with the appropriate safety precautions. If you mess this up you will turn your PSP into a lifeless and possibly explosive plastic brick.

The basic, high-level steps are as follows:

  1. Create a Pandora's battery. This is a battery that has been modified to make the PSP into boot from the memory stick.
  2. Create a Magic Memory Stick. This is a memory stick that has been specially formatted to boot and perform a firmware upgrade. Note that there are some limits on the capacity and brand of memory stick that can be used; see the guides above for more details.
  3. With the PSP powered off and the battery removed, insert the magic memory stick into the PSP.
  4. Insert the Pandora's battery. The PSP will power on automatically boot from the magic memory stick.
  5. Use the software on the magic memory stick to install the custom firmware. On the PSP Slim the display is blank, so you just have to hit X and wait. The lights on the front of the PSP will blink for several minutes. The PSP will automatically power off when the installation is finished.
  6. Remove the Pandora's battery and the magic memory stick. The memory stick can be reformatted and used as usual. The Pandora's battery can not, because some of the battery's safety features are disabled as part of the conversion process. In other words, do not attempt to use the Pandora's battery as a regular battery unless you want your PSP to melt into a smoldering puddle of goo.
  7. Power on the PSP using a regular battery or the power cable. Congratulations, you are now running the custom firmware.

The hardest part of this process is creating the Pandora's battery. If you know someone with a PSP that already has the custom firmware installed, then they can run an application on their PSP to temporarily "soft-mod" a regular battery into Pandora's battery.

If you don't know anyone with a PSP that already has the custom firmware installed, then the only way to convert a regular battery into a Pandora's battery is to "hard-mod" it; that means cutting open the battery casing and disconnecting one of the leads on the internal circuitry.

The guides I read (see above) have plenty of pictures, but I was still surprised by how small the pieces actually were. Here's a picture I just took of my Pandora's battery, including a ruler and quarter as size references:

Inside a Pandora's Battery
Inside a Pandora's Battery

Creating a Magic Memory Stick is much simpler. Basically you:

  • format the memory stick in a special way (using mspformat)
  • copy the necessary firmware installation and upgrade files into place
  • generates an Initial Program Load (IPL) file,
  • copy the generated IPL file to the first sector of the memory stick (using mspinst)

If you're using Windows, the "TotalNewbi Installer" and "Pandora Easy GUI" tools can automate this process. In theory, anyway. When I tried to use them in my Windows XP VMWare instance, they both had problems. The TotalNewbi Installer simply refused to work, and the Pandora Easy GUI blue-screened XP each time I ran it.

Here's what finally worked:

  • used Pandora Easy GUI to copy the firmware files into place and generate the installer definition file (mspinst.idl)
  • used dd in Linux to copy mspinst.ibl into the first sector of the Memory Stick

The good news is that creating the Pandora's Battery and Magic Memory Stick are the hardest steps in the process. Once you get past them, everything else is relatively straightforward. Even better, the process can be used to install custom firmware on any PSP, regardless of hardware model or firmware version.

That's it for me. If you're interested in the history and technical details of PSP homebrew, check out this extremely detailed PSP homebrew Wikipedia entry.

Syndicated 2008-02-16 15:37:32 from Pablotron: News

...as if things weren't broken enough around here

Hello from the new server!

I managed to glom things together just enough to get the bit-rot that is this site's code running on the new server. All the usual caveats about brokenness apply.

Syndicated 2008-02-05 04:47:12 from Pablotron: News

Reddit Content Filter 0.4

Works with the latest changes to Reddit.

Local copy:

There was a suggestion in the comments on User Scripts about auto-downmodding blocked articles. I kind of like the idea. Does anyone have any opinions on that? Comments are broken at the moment, but feel free to email me.

Syndicated 2007-12-04 01:44:40 from Pablotron: News


I got the LCD power adapter, power supply, and new CPU fan for my HTPC. Here's a picture of it in my entertainment center:

htpc in entertainment center

(And yes, I know my carpet needs to be vacuumed).

Syndicated 2007-11-25 20:16:44 from Pablotron: News

HTPC Mayhem!

I've been planning to build an HTPC for quite a while now, and I'm finally doing it. I got an Antec Fusion Black case for my birthday, and I went out and bought the rest of the parts yesterday evening. Here's the hardware I'm using:

The other pieces were all spare parts and aren't particularly interesting. This post is about the Antec Fusion Black. Let's start with the pros:

  • Built-in case fans are extremely quiet.
  • Enough room for a standard ATX power supply.
  • Same width and style as standard home theater gear.
  • Front-mounted USB, Firewire, and HD audio ports.
  • Built-in IR port.
  • Built-in programmable LCD.
  • Several in-case cable ties to keep things properly routed and organized.

And the cons:

  • Three-compartment design makes running anything other than power and SATA cables a bit of a hassle. It took a bit of magic to thread a standard EIDE cable from the motherboard compartment to the DVD/LCD compartment, for example.
  • The IR receiver is for MCE-compatible remotes only; it doesn't work with standard universal remotes, so don't even bother.
  • Linux support sucks. I believe you can get everything working, but doing so requires a bit of effort. See below for more information.
  • The included manual is horribly out of date and contains errors and omissions. Your best bet is to use the manual as toilet paper and download the PDF from Antec's product page, although that manual is still dated. Both versions claim that the motherboard has a 3-pin power supply fan signal connector cable, and no such cable exists in my case. There is also a mysterious two-pin purple and black cable labeled "M/B PWR" that is not documented in either manual (this thread on AVS Forums explains what it's for).
  • Non-standard power connection for the LCD and IR receiver. This only matters if you need to replace the power supply; see below.

Fortunately I've already decided to buy a Harmony remote, so the MCE remote requirement is a minor inconvenience and an excuse to go buy a new gadget.

The most irritating problem so far is that the power supply fan is extremely loud. I think my PSU is probably defective, because it doesn't make any sense to design a sound-isolating case with extremely quiet case fans and then put a power supply that sounds like an air raid in there. Alternatively, the noise might be related to the non-existent 3-pin power supply fan signal connector cable mentioned above.

Anyway, I don't really want to send the case back, so I ran to Microcenter and picked up a new silent power supply. That's when I noticed the non-standard cable that powers the LCD/IR receiver, and the following blurb tucked away in the manual:

Note: If you choose to swap the included power supply with another power supply, please call Antec Customer Service to purchase a special 24-pin Extender with the 3-pin connector to power the display.

I've already ordered the adaptor from Antec's web site; I figure even if I figure out how to quiet the existing power supply it's worth having so I don't end up without the LCD and IR port if the power supply failure in the future.

Next up, Antec Fusion Linux support. The LCD is not officially supported in Linux by Antec. The good news is that the LCD in the Fusion V2/Black is better than the VFD display included in the original V1 Antec Fusion case. Unfortunately it is much harder to find documentation on the newer display. The newer display also requires a couple of patches and some config file twiddling.

Here's what you need to do, as of today:

  • Install patched versions of LIRC 0.8.2 and LCDproc 0.5.2. You can get the patches from here.
  • Follow the instructions exactly for patching and compiling LIRC and LCDproc.
  • When you recompile LIRC, select "Soundgraph iMON MultiMedian IR/VFD", not "Soundgraph iMON PAD IR/VFD".
  • After you patch LCDproc, you need to do the following or LCDproc won't pick up the changes from the patch:

      aclocal && automake && autoconf
      ./configure --enable-drivers=imonlcd

  • Compile and install both LIRC and LCDproc.

  • Find the [server] section in /etc/LCDd.conf and add the following lines:


  • Add this section to /etc/LCDd.conf:

      # do NOT set the Size, if you do it won't work

  • Make sure the LIRC modules are loaded:

      modprobe lirc_dev && modprobe lirc_imon 

  • Start up lircd and LCDd, and things should be working.

If you're using or newer the patches above will not work; you'll need these updated patches against the CVS version of LIRC. You'll still need to follow all the steps above, even with the updated patches.

That's all for tonight. It looks like configuring the motherboard in will be a battle too; I'll have more details as events warrant.

Syndicated 2007-11-14 03:33:06 from Pablotron: News


I got sick of the page being so slow, so I this morning I made some fairly destructive slash-and-burn style changes under the hood. Things should be mostly working again, with the following exceptions:

  • Themes: They're busted until I get a chance to patch them up. I have no idea what will happen if you try and use them, but probably nothing good (for you, not me).
  • New Accounts: You can wait a day or so to harass me about my latest inflammatory post. Or send an email instead.
  • Screenshots: Yeah my desktop from 1998 has a lower resolution than your cell phone. So what?

There may also be other stuff broken, too. I've tried to keep URLs for articles and whatnot the same, but your mileage mamy vary. Today is the first of several iterations away from the almost decade-old code this site is running.

Syndicated 2007-10-17 08:52:04 from Pablotron: News

EasyCookie: Easy Javascript Cookie Management

Ever tried to read and write cookies in Javascript? If you have, then I'll wait until you've stopped frothing at the mouth and pounding your keyboard.


Feeling better? Good. I just released the first public version of EasyCookie, a simple cookie library for Javascript. Using EasyCookie is, well, easy. For example, here's how you get a cookie:

  // get a cookie

val = EasyCookie.get('my_cookie');

And here's how you set one:

  // set a cookie

val = 'a random value that i want to save as a cookie';

EasyCookie.set('my_cookie', val);

And, if you haven't already guessed, here's how your remove a cookie:

  // remove a cookie


But what about all the extra crap you usually have to fight to get working, like the domain, path, and expiration? Don't panic! EasyCookie.set takes a hash of additional attributes as an optional third argument. Here's another example of EasyCookie.set, this time with the optional hash:

  // value to set

val = '99 bottles of beer on the wall, 99 bottles of beer!';

// set a cookie that expires in 10 days, and limit the scope to

// "https://foo.example.com/some/path"

EasyCookie.set('my_cookie', val, {

  // expires in 10 days

  expires: 10,

  // limit cookie to domain 'foo.example.com'

  domain: 'foo.example.com',

  // limit cookie to path '/some/path'

  path: '/some/path',

  // restrict cookie to secure pages only

  secure: true


Checking to see if cookies are enabled just got a whole lot simpler, too:

  // are cookies enabled?

enabled = EasyCookie.enabled;

// harass user with annoying dialog about their cookie status

alert('Cookies are ' + (enabled ? 'enabled' : 'not enabled'));

Best of all, EasyCookie is BSD licensed, and the minified version weighs in at a measly 1873 bytes. Anyway, here ya go:

PS. Yes, I realize the link above are to version 0.2.1 of EasyCookie, even though this is the first public release. In internet years the backend to my page is older than your grandmother. Imagine trying to explain how to release software to your grandmother.

Syndicated 2007-10-17 02:28:43 from Pablotron: News

New Version of Reddit Content Filter

Reddit updated their site layout yesterday, which broke my Reddit Content Filter Greasemonkey script. I just posted a new version a few minutes ago, along with my Reddit Navigational Access Keys script, which I apparently never posted to User Scripts.

I've also hosted both files here:

Syndicated 2007-10-16 08:11:09 from Pablotron: News

Brain Dump: Random Migration Notes

I've been using the migration and some recent side projects as sandboxes to try out new things. Here's a semi-random list of useful tidbits I've picked up along the way:

  • Better mod_rewrite magic: Google turns up plenty of mod_rewrite examples on automatically stripping the dreaded "www." prefix from URLs. Unfortunately, most of them appear to be incorrect. Here's the most common solution:

    RewriteCond %{HTTP_HOST} ^www.example.com$  [NC]
    RewriteRule ^(.*)$  http://example.com/$1   [R=301,L]

    What it's supposed to do is redirect visitors from http://www.example.com/whatever to http://example.com/whatever, but what it actually does is redirect visitors to http://example.com//whatever. It's minor, but it was driving me nuts (Arrrrrrr). Anyway, here is the correct solution:

    RewriteCond %{HTTP_HOST} ^www\.             [NC]
    RewriteRule ^/(.*)$  http://example.com/$1  [R=301,L]

  • mod_deflate: Saves a ton of bandwidth, works great in IE7 and Firefox. The stock settings don't include a couple of common MIME types; here's the list I'm using: text/html text/plain text/xml text/css text/javascript application/x-javascript text/csv

  • XCache: Fast PHP opcode cacher that actually works with recent versions of PHP. I tested several Wordpress, Gallery, and custom PHP sites without incident, and my (incredibly rough) benchmarks showed about a 4-7% increase in mean transfer speed.
  • ExtJS Builder: I decided to test the ExtJS builder for a personal project. The interface is a bit finicky; it took me about 5 tries to get all the dependencies for my project selected. Here are the results:


    Note: The "Minified" column is the total file size after being shrunk with Douglas Crockford's excellent jsmin, and the "Deflated" column is the actual transfer size (according to Firebug) after being passed through mod_deflate.

    Not too shabby for 20 minutes of work. I'm a little bit disappointed by the stock mod_deflate compression ratio, so that may need a bit of tweaking.

  • Backgrounding Mercurial Hooks: The Mercurial book has an excellent chapter on hooks. What it doesn't mention, unfortunately, is how to run hooks in the background. I have a semi-lengthy outgoing hook (roughly equivalent to a client-side post-commit for you Subversion weenies) that connects to a web server via ssh and performs some deployment tasks, and all attempts at backgrounding a shell script eluded me. Well, it turns out Mercurial has an extra hidden file descriptor that has to be closed in order to background a hook. So here's my down and dirty client-side background deployment hook:

    # outgoing hook script that connects to web server and deploys
    # the latest site from tip.  It is run in the background after a
    # successful 'hg push'.
    # options
    opt = {
      # remote hostname
      'host' => 'web',
      # remote command (relative to my home directory)
      'cmd'  => 'bin/update_site.sh',
      # client-side log (set to /dev/null to disable)
      # 'log'  => '/dev/null',
      'log'  => '/tmp/site_update.log',
      # delay (in seconds) before update
      'delay' => 3,
    # fork and run update in background
    pid = fork {
      # close stdin, stdout, and stderr
      $stdin = $stdin.reopen('/dev/null', 'r')
      $stdout = $stdout.reopen(opt['log'], 'a')
      $stderr = $stderr.reopen(opt['log'], 'a')
      $defout = $stdout
      # close all other file descriptors
      # NOTE: mercurial appears to have a hidden fd laying 
      # around somewhere, so this evil is necessary...
      (3..99).each { |fd| IO.new(fd).close rescue nil }
      # wait for push to finish
      # (this should poll the hg server instead, to handle
      # lengthy pushes)
      sleep opt['delay']
      # run update command and exit
      args = ['ssh', opt['host'], opt['cmd']]
      # never reached
      exit 0
    # reap child and exit
    flags = Process::WNOHANG | Process::WUNTRACED
    Process.waitpid(pid, flags)

Update: Markdown really mangled my markup this time around. Usually it's pretty tolerant, but apparently this post was just a bit too much. Oh well...

Syndicated 2007-10-15 06:16:32 from Pablotron: News

23 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!