T8Launcher for Tapwave Zodiac

I’ve just finished the first Alpha version of T8Launcher for Tapwave Zodiac. This is a pretty minimalistic launcher that uses a T9-like system to let you launch your apps. It’s only an alpha, but from my experience it seems almost 100% stable (in fact, the latest Alpha didn’t crash on me once). There are a few remaining issues that you’ll find listed in the FAQ below, but nothing serious. Still, I’m not responsible for any unintended behavior or any crashes.

Download:

FAQ:

  • How to install T8Launcher? Just Hotsync the PRC file contained in the ZIP file… that’s all
  • How to exit T8Launcher? Enter “Home” to get back to the original Zodiac Launcher
  • How to disable T8Launcher? Unfortunately, that’s not possible (yet). If you want to disable it, you have to uninstall it.
  • How to uninstall T8Launcher? Just use a third-party utility like Filez to delete the T8Launcher database.
  • I see some strange programs like “MMConduit” amd “Error Reporter” in T8Launcher. What are these? These are hidden system utilities. So far T8Launcher ignores the “Hidden” file attribute of PalmOS. Just ignore these.
  • A few programs with very long names leave display artefacts on the “ABC1” button. How can I get rid of these? You can’t, this is a known issue… just ignore it for now.
  • The program list looks pretty unsorted. Am I missing something? The only sorting priority right now is the position of the code match, so for example for “ABC1”, “MN50” Another World comes before Manticore. However, there is no alphabeitcal order.
  • Even after entering the full name of the app another app gets listed first, for example Address XT after entering Address. Just use the “Down-Arrow” button to cycle all results. You’ll get there eventually.
  • Is T8Launcher much slower than the original Zodiac Launcher? Actually, it’s a hell of a lot faster, thanks to the native ARM code and simple structure.
  • How can I launch an application from card? Unless you use a tool like PowerRun, you’ll have to exit T8Launcher and use the standard launcher instead.
  • How can I find out which code I have entered? You can’t. But you can use the “Left-Arrow” button to fix spelling mistakes.
  • How do I enter unlisted characters like space or asterisk? Don’t. T8Launcher ignores anything but a-z, A-Z and 0-9. For example “my App**” would simply become “myapp”.
  • Can I create my own skin for T8Launcher? Well, yes and no. There are no special tools, but you can simply use a normal PRC editor to modify the resources.
  • Why is its name T8Launcher? On normal T9 cellphones, you actually need 10 keys (0-9) to enter a meaningful message. T8Launcher needs 9 buttons for input, so the logical name is T8.
  • How will development continue? I don’t know. I might create a more polished version and try to sell it for $1 but that’s just an idea… Anyway, this Alpha version will always remain free.
  • Why are a few buttons not centered vertically? I made a mistake when creating the images and I haven’t gotten around to fixing it yet.
  • Which tools were used for this? PRC-Tools, PEAL and PARM

Feel free to use the comment section for suggestions and/or bug reports.

Another World for Tapwave Zodiac

I think it’s high time I started posting about something for my beloved Tapwave Zodiac 2 and frankly, I think there has never been a better reason than the release of Another World (a.k.a Out of this World) for the Zodiac by Chrilith.

And what a port it is! This is probably the first port of a PC game that truly feels like if it was made for the Zodiac. In fact, this game looks even better than the original PC version, and not only because the screen is a bit smaller, but because it indeed features a higher resolution than the original (of which you can see the intro movie on the left).

But, first things first: Another World is what most people would describe as an Action Adventure game, where you run and jump through large levels, always looking for the next item, while shooting at everything that comes in your way.

The game starts with a long and extremely well done intro sequence that explains how you end up in this bizzare world and this is something that continues throughout the game. Wherever you turn, you are greeted by yet another movie and to tell the truth, that’s what keeps you going. And indeed you’ll need all the motivation you can get to pass all the levels in this game (I have to admit that I never got very far, so if you really want an in-depth review about the WHOLE game, you’ll have to look somewhere else).

But enough about the game itself, most of you have probably played it anyway while in highschool (I still have my original SNES cartridge). I said at the beginning that I think this port is special in that it actually feels like a native Zodiac game:

It starts with the fact that Another World doesn’t display some oddly coloured launcher screen or annoying debug messages. Instead you get a nicely done welcome screen that, which after maybe half a second of loading gives way to the intro sequence. An intro sequence with loud digital thunder, wonderful music and native 480×320 resolution.

That’s right: 480×320, not 320×200 like the PC version. That’s because Another World is one of those few 2D games that use vector graphics instead of the usual raster graphics. And unlike raster graphics, vector graphics stay sharp no matter what resolution you choose. Oh, and not only do they look great, but they are also really fast. There’s never any noticeable slowdown and if I had to guess I’d put the framerate somewhere around 30 fps.

Next are the controls, which are special in that they are really simple. You duck, jump and walk with the analogue stick and you do pretty much everything with the yellow button: run, jump, shoot, activate, build up a shield and so on. I know it sounds crazy to have so many controls on a single button but it really works perfectly. The only button that behaves slightly unusual is the Function button: This button takes you to a menu, where you can enter a four letter code, which will take you to the level specified by the code. The reason for this is that sadly, Another World doesn’t have a savegame function. Instead you are given a code at the beginning of each level. I really hope that later versions will automatically remember any given codes, because this is pretty much the only evidence that you’re not dealing with a native Zodiac game.

Speaking of differences to a native game: The installation is of course slightly different as well. You have to get the files from the PC version and put them (together with a few files from the Zodiac version) on the SD card. Don’t worry, it’s about 1MB and you don’t need any additional libraries like Timidity. Sadly, the legal situation is a bit… well… difficult… to say the least. The PC version is what most people refer to as “AbandonWare”. That means it’s not available for purchase anymore, but the copyright holder is still alive and well. On the internet it’s now common practice to publish these “abandoned” games (just search for abandonia on google), even without the consent of the original author, but it is almost certainly not legal when you’re not a registered library like archive.org. On the other hand, there is no victim with true abandonware, so I’ll leave this up to you (while I’m holding on to my SNES cartridge).

Object Oriented Programming and Event Handlers

When I started writing Object Oriented Javascript, there was one major pitfall: Event handlers. Event handlers are functions that are launched when a certain event occurs inside the browser, say a click on an image.

Most people are familar with the onclick, onload (…) attributes in HTML and a few selected ones even know how to work with addEventListener and attachEvent (see below), but no matter what system you use, there’s one thing that never works and that’s using event handlers in an object oriented application.

Why? Well, for some reason (I wish I knew which one), both the W3C, which is the consortium for web standards and Microsoft (which is a company against standards, but they usually behave the same way) defined event listeners to take exactly one parameter, and that’s the function which is supposed to be called when an event occurs.

Time for sample code. Imagine you have three buttons and want each one to display its number when you click on it. And imagine you don’t want to do this manually, because there could be as many as 1000 buttons. Here’s the HTML part:

<html>
 <head>
  <title>HelloButton</title>
  <script></script>
 </head>
 <body>
 </body>
</html>

OK, now let’s define our “Button” class. A class is nothing more than a blueprint which you can lateron use to create objects that are all constructed according to this blueprint… In Javascript they are really easy to make, you just create a constructor function and that’s pretty much it. The only differences to a normal function are that:

a) A constructor can’t return anything, because it always returns the object it created.

b) You can use “this” to set properties of that object (object, not class: each object has its own properties, for example two objects of the class “person” might have a property “name”. For person1, this could be “Hans”, for person2 “Peter”).

So, to define a button class with a property “buttonTitle” and a HTML element to display the button all we have to do is this:

function button(title){
 /* Create an input element and save a reference in the element property */
 this.element=document.createElement("input");
 /* Set the type of the HTML element to "button" */
 this.element.setAttribute("type","button");
 /* Set the label of the HTML element to title */
 this.element.setAttribute("value", title);
 /* Append that element to the HTML body */
 document.getElementsByTagName("body")[0].appendChild(this.element);
 /* Set the title property to the supplied title */
 this.title=title;
}

Nice, huh? OK, one more thing before we actually get to the event handlers. To define a function that can also use “this” (that’s called a method) we have to use a special notation…

classname.prototype.methodname=function(parameters){code}

Looks strange, I know. But it never really changes, so all you’ve got to do is copy paste. Let’s say we want to add a “showTitle” method that uses alert() to display this.title:

button.prototype.showTitle=function(){
 alert(this.title);
}

Not that hard, is it? OK, now we’ve got everything working, but we still have to actually create the objects using a simple “for” loop (we do this inside a “main” function which we specify for body.onload, because otherwise the code which tries to append something to the body might run before the body is actually there) , so now our whole document looks like this:

<html>
 <head>
  <title>HelloButton</title>
  <script>
function button(title){
 this.element=document.createElement("input");
 this.element.setAttribute("type","button");
 this.element.setAttribute("value", title);
 document.getElementsByTagName("body")[0].appendChild(this.element);
 this.title=title;
}

button.prototype.showTitle=function(){
 alert(this.title);
}

function main(){
 var buttonObjects=new Array();
  for(var i=0;i<3;i++){
   buttonObjects[i]=new button("Button #"+i);
  }
}
  </script>
 </head>
 <body onload="main()">
 </body>
</html>

So now we have the button class, the objects and the HTML buttons: Hurray! But nothing happens when we click them, because we haven’t defined any behaviour yet.

So let’s extend our constructor function (“function button(title)…”) a little. You can look at the previous post if you want to use proper eventListeners, but right now we’re going to just use the onclick attribute.

The seemingly logical thing would be to just add a line that sets the onclick attribute to this.showTitle, right?

this.element.onclick=this.showTitle;

Sadly, this doesn’t work… we don’t get this.title! Why? well, when an event handler gets executed, it gets executed in such a way that “this” means the element that sent the event, in the case the HTML “input” element, not our object.

So what do we do? Well, there’s a nasty little method that every function in Javascript has: this is the “call” method and it executes a function so that “this” means the first parameter. So what we want to do would be something like:

this.element.onclick=this.showTitle.call(this);

Looks nice I know, but sadly it still doesn’t work, because that line actually evaluates this.showTitle.call(this) and then sets this.element.onclick to the value it returned.

But if we wrap this inside yet another function, we’re at least getting closer: Now onclick is at least set to a function, eventhough it still doesn’t work, because “this” is still the HTML element.

this.element.onclick=function(){this.showTitle.call(this)};

The trick is now to actually create a function that we can somehow pass “this” to and which will then return a new function which has “this” hardcoded to the right value. The thing we need here is called Javascript closures and you can easily find documents that explain in 100 or more pages what it is and how it works… but we really only need to know how to use it.

First we create a new function outside any object. Let’s call it methodize. This function should take as a parameters a given function and a reference to “this”, we call this “scope”:

function methodize(methodize_func, methodize_scope){
}

As we said before methodize should return a function:

function methodize(methodize_func,methodize_scope){
    return (function(){});
}

And what should that function contain? Exactly. The nasty “this.showTitle.call(this)”, but because we designed this for any function, not just “this.showTitle” we use “methodize_func” instead and “methodize_scope” instead of “this”.

function methodize(methodize_func,methodize_scope){
    return (function(){methodize_func.call(methodize_scope);});
}

Now, when we run methodize we get a function that when executed calls the given method in the given scope. We can now asign that to onclick

this.element.onclick=methodize(this.showTitle,this);

And that’s it! Now we get the eventListener executed in the correct scope! I know it seems hard and unneccessary, but once you get used to it, it’s really just copy/paste. Here’s the full code again:

<html>
 <head>
  <title>HelloButton</title>
  <script>
function methodize(methodize_func,methodize_scope){
    return (function(){methodize_func.call(methodize_scope);});
}

function button(title){
 this.element=document.createElement("input");
 this.element.setAttribute("type","button");
 this.element.setAttribute("value", title);
 document.getElementsByTagName("body")[0].appendChild(this.element);
 this.title=title;
 this.element.onclick=methodize(this.showTitle,this);
}

button.prototype.showTitle=function(){
 alert(this.title);
}

function main(){
 var buttonObjects=new Array();
  for(var i=0;i<3;i++){
   buttonObjects[i]=new button("Button #"+i);
  }
}
  </script>
 </head>
 <body onload="main()">
 </body>
</html>

P.S:
There’s one thing that we could add to our methodize function and that’s passing of the event and any other parameters to the methodize_func.

It’s really not much of a deal

function methodize(methodize_func,methodize_scope){
    /* Copy the arguments array, which contains all parameters
       to  methodize_args, except entries #0 and #1  (methodize_func
       ,methodize_scope) */
    var methodize_args=new Array();
    for(var i=2;i<arguments.length;i++) methodize_args.push(arguments[i]);
    /* Return a function that takes an event parameter itself
       and passes it on to methodize_func, along with methodize_args */
    return (function(evt){methodize_func.call(methodize_scope,evt,methodize_args);});
}

And voilà: Suddently our target function runs not only in the correct scope, but it also receives the event that triggered its execution as first parameter and whatever you specified after methodize_scope as an array.

A few words about Javascript

I’m a bit of a Javascript fan and since I don’t have anything better to do right now I though I could tell you about a few typical errors that even the guys over at Google, along with 99% of all pages I know, make.

The problem is that people learn Javascript as well, a Script language, not a proper programming language… which is a shame because Javascript itself is probably one of the most comfortable languages I know. And because they don’t see it as a proper programming language they just hack their code until it works… for now.

The worst abomination onto JS is probably browser sniffing: It’s a pretty simple technique that’s easy to understand which is probably why beginners tend to use it, however it’s also a technique that a) requires a lot of testing, b) requires a lot of updates and c) goes completely bonkers when new browsers are released.

What browser sniffing (a.k.a. useragant sniffing) does is “ask” the browser about itself and then taking appropriate measures. Seems simple, right?

Well if it is so simple, then what would happen if you ask a browser if it is a “Mozilla”… Surprise! Pretty much all major browsers (including Internet Explorer) claim to be Mozilla. So let’s ask about MSIE to make sure which Mozillas are actually Internet Explorer. Oops, Opera and a few others report that too. OK, then how about finding out which ones are really Mozilla by looking for “Gecko”. Oh, Safari says it’s “like Gecko”. If you want an almost complete list, have a a look here.

You see: it doesn’t work and it’s really a shame that people still use this first-grader technique if there’s a much easier alternative: Method sniffing.

In Javascript, every function or method that does not exist has the value “undefined”. So if you want to use something that you are afraid isn’t available everywhere, you just ask if the browser supports it directly, instead of asking for the browser and then assuming that a certain browser supports this or that.

For example, lets say we want to use the addEventListener method and as a fallback the attachEvent method, then we simply create a wrapper function:

function wrapperAddEventListener(obj,type,callback){
if(obj.addEventListener!=undefined) obj.addEventListener(type,callback,false);
else if(obj.attachEvent!=undefined) obj.attachEvent(“on”+type,callback);
else alert(“Sorry, your browser is not supported”);
}

And that’s it. And it works for pretty much everything, except for some strange HTML behaviours. Now my minions: Spread the word.

The next time I’ll be looking at the scope of Variables in JS… a topic that isn’t understood by more than a handfull of people, eventhough it’s not that difficult. See you next time.

Welcome everybody

I think it’s high time I start yet another blog, after the last one has disappeared in the great free.fr cleanup.

My name is Hans Schmucker and I’m a student at the University of Applied Sciences, Heidelberg, Germany… while I’m not in a job yet, there are already quite a few things I’ve worked on and the number of people using my software, or using software that’s based on my code has probably well surpassed 10,000 (my little Patience game alone has well over 6,000 users per day, so 10,000 is a safe bet).
What else… hmm… my specialty right now is Web Application Development (can you spell AJAX 😉 ), but I’ve also worked quite a bit with C on mobile platforms ( Quest for example uses some of my code for the PalmOS backend).

So, now I want to offer you a quick look into the mind of a developer and PalmOS enthusiast 🙂

What to start with? Ah, recent events: Microsoft‘s Steve Ballmer threatening Linux users, that they might get sued for violating Microsoft’s patents.

To tell you the truth: Linux almost certainly violates Microsoft’s patents. Why? Because nowadays pretty much anything you do violates some patent, due to the sheer number of patents. And Microsoft certainly violates a few itself. The difference? Microsoft has thousands of patents, so if somebody wants to sue them, they just threaten to sue that company for violating their patents. It’s a pretty good ecosystem, that is if you have the money to register thousands of patents just so you can defend yourself… or in other words, if you don’t care about a million dollar just for patents that you’re never going to use.

That’s why Microsoft is pushing patents wherever they can: They are the winner in a system where the number of patents you have equals power.

The alternatives? Well, for example you could make patents more expensive for bigger companies. If a company has to sacrifice 0.5% of their profits for a patent, then they’ve got to be more careful. A smaller company on the other hand could at least apply for 5 patents each year to protect real inventions that they often can’t afford to protect right now.

But let’s get back to the topic at hand: Microsoft vs. Linux.
As I said before, Linux almost certainly violates Microsoft’s patents, so why does Microsoft not sue? Well, because whoever they sue would certainly question if Microsoft’s patents are valid and Microsoft prefers potentially invalid patents, that they can use for spreading FUD to no patents at all. While I’m not a lawyer, I know a thing or two about patents and there are two interesting points that the patent office is supposed to check before they grant a patent (sadly they never do): Originality and Significance.

Basically that means that you can’t patent something that’s been used before (like patenting algebra, although that has already happened) and you can’t patent something that’s trivial (although that has happened countless times as well).

Both points are fairly dangerous to Microsoft, because they can’t really claim any new inventions as far as Operating Systems are concerned. WindowsNT (that’s the basis for NT, 2000, XP and Vista) is basically an attempt to port Windows95 to a unix-like environment. Yes. Unix. The same system that Linux is based on. And their user interface: Well I won’t even go into much detail, but for example GEM looks way to similar and it’s a lot older.

I think I’ll stop here and let you think about it yourself. See you next time.

Hans Schmucker