Tapperware - Tapping into Mobile Technology

A blog about Mobile Technology, Politics as far as they affect technological development and just random gibberish.

Friday, January 18, 2008

Secure web applications - using JS to create a new web language

When you look around on security mailing lists you'll probably an increase in security warnings relating to web applications... many of them based on JS code injected into a webpage.

This has lead to the uncomfortable situation where pages that are based on usercontent can not trust their users to provide JS as part of their submitted content. So now we can share video, audio and other passive media but anything interactive is out of the question.

What to do about it? The JS security system is entirely based on domain names and some providers have resorted to running all user js code on a seperate domain... but this again limits the usefulness of JS because it can only operate within the assigned iFrame. Others are trying to run the JS code through code analysis tools to find out if it is doing anything "forbidden".

But who are we kidding? Blacklist attempts have never worked so far and the thing about web security is that even a single attack can leave data from dozens of apps exposed.

The alternative is quite simple, but to my best knowledge has never been tried: Implementing a second language in JS, running protected in a seperate sandbox, allowing only whitelisted calls and if necessary filtering the results. Is this possible? Certainly? Is it hard? Not as hard as one would imagine? Is it slow? Definately slower than true JS but still fast enough to be of use.

Let's tackle these questions one by one:

Is it possible? Every language that can implement basic text parsing can implement it's own parser... it's really as simple as that. And it JS it's even easier because we have a bunch of text processing tools like RegularExpressions that make parsing quite straight-forward and simple.

Is it hard? Not really... many of the requirements for the interpreted language can be mapped to native behaviour. For example: the garbage collector can work for the interpreted language as well if we map stacks and variables in the interpreted language back to native objects.

Is it slow? In order to answer this question we have to remember how code is usually stored in high level languages: The CodeDOM. The codedom is a simple, object-based tree structure where any number of atoms make up expressions. Once we have parsed the expressions into this DOM and inserted all implicit behaviour, executing code is really just a matter of walking this tree. So each interpreted operation means running the atom handler and following the tree. The atom handlers usually don't change and can therefore be compiled by the JS handler and the jump to the next atom is just following a single reference. Combine that with the fact that we can replace known atom combinations with optimized functions and you'll see that this is fast enough for the majority of simple web apps.

Just think about it what people could do if their apps were not restricted to their iFrames... youTubeOS? mySpace dynamic layouts? The sky would be the limit (That and the rules inserted into the interpreter... mySpace could opt to give users full access over the page's elements, but not their ads and not the document and window elements).

Labels: , ,

Sunday, January 13, 2008

If I had a Hammer OR Why RFID in passports is a really bad idea...

First things first: I actually do have a hammer and I know how to use it when it's time to get my new RFID-enabled passport. It's a fairly easy method to disable this ugly tracking device.

The more important question is why should I do it? Well there are a couple of reasons, so let's make a list:

Let's start with the basic problems of any encrypted data:
1. I don't want the state to identify me... sure they say the data is encrypted, but there was no way for officials to read it, then we wouldn't have to carry it around... so the key is somewhere and let's face it: If any part of our state has this key then it won't take long until every single policestation or whatever has access to it.
2. I don't want others to identify me ... if the key is available somewhere, then it won't take long until it leaks out.

But are there other scenarios where the chip could reveal your presence. Even if the encryption was not compromised?
3. Hell yes. With RFID anybody can track you, even without the encryption key. This is by far the most interesting point. Lets assume for a moment that the data is stored 100% perecent secure and that the key is not available to anybody (I know, it's difficult but let's try). Then the chip is still sending out the encrypted data which may not be readable by itself, but it's still a unique identifier. It says that person XY was last seen going to a bank, then going to a chemical supply firm and finally after a brief visit to Starbucks boarding a flight to Saudi Arabia (at least if there's a RFID scanner at all these locations.... this probably isn't the case now but it's still a possiblity we'll have to deal with). Maybe you can't find out who person XY is, but you sure can find out what he's been doing as XY has left the same digital fingerprint at all these locations. And if XY has used another identifier, let's say a credit card, at at least two locations with an RFID scanner, we even know that this person is me.

Now this may all be very useful when trying to catch a criminal (eventhough it violates about every privacy law we've got), but this kind of information is available to anybody who can afford an RFID scanner. Let's assume a group of stores agrees to exchange RFID information... not with any other authority, just among themselves. Sounds pretty harmless doesn't it? But from this information alone, combined with the list of items bought while you were at the store and matched across multiple shopping sessions and some easy statistical analysis they'll get something like this:

Usually around 1pm at store A, usually buys sweets, pizza, Coke and bathroom acessories. around 6pm either at store B or C. This is only a tiny bit of what they could derive but already they'd know where you live, where you work and what you buy, just like that.

And this would only be the "normal", "marketing" way of analysing your data. Criminals are much more inventive...

I'm not asking you to do anything but think about it how your privacy gets a beating with RFID passports.

Labels:

Sunday, August 26, 2007

CSI moves to Origo

CSI, the Javascript client side inclusion library, is moving to a new home over at Origo... if you're interested in joining the project, just create an account over at Origo and drop me a line.

You've gotta love some quotes

Every once in a while, you come across a quote that is so absolutely stunning, you simply cannot believe that the person who wrote it was crazy enough to even put it in writing. This is just such a case.


From: Bill Gates
Sent: Saturday, December 5 1998
To: Bob Muglia, Jon DeVann, Steven Sinofsky
Subject : Office rendering

One thing we have got to change in our strategy - allowing Office documents to be rendered very well by other peoples browsers is one of the most destructive things we could do to the company.

We have to stop putting any effort into this and make sure that Office documents very well depends on PROPRIETARY IE capabilities.

Anything else is suicide for our platform. This is a case where Office has to avoid doing something to destroy Windows.

I would be glad to explain at a greater length.

Likewise this love of DAV in Office/Exchange is a huge problem. I would also like to make sure people understand this as well.

Monday, August 20, 2007

CSI - Client Side Includes

This has plagued me for the past few months and I simply couldn't find any nice, simple, small solutions available. If your Javascript code consists of separate parts, you probably have them separated into any number of .js files... problem is: If these JS files, like any self-respecting library, want to include other JS files, then all you can do is write down it into a comment. Then, when you start a new project that would benefit from that library, you have to add the library itself via a script tag, look at the comments, find that library that your library needs, add it via a script tag, look at the comments of that library... you see what I'm getting at.

The alternative would be to let a PHP, or other script do that task... but that would either require you to move all your projects to your web directory or run that script every time you want to test your code. Additionally, when an error occurs during runtime, you won't get the file and line number of your working files, but the one in the compiled file. Not very satisfactory.

Enter CSI - Client Side Includes.

CSI is something in between a library and a framework. It's tiny (the core is <2k uncompressed) and requires only minimal modifications to your code.

For more details (as well as a demo) and the download, check here.

Sunday, August 19, 2007

Smoothly fading slideshows and hover buttons

This was done per request and while the code is not really beautiful, it works just fine.

"Fade" is a small (8kb uncompressed, 2kb compressed), standalone Javascript library which provides smooth slideshows and hover buttons, while requiring only an absolute minimum on coding knowledge. Just set a few class attributes, copy the loader code and voilà. It even degrades gracefully if there's no Javascript available.

See it in action, along with a short introduction here.

I'd love to hear some feedback, too. :)

(License is CC Attribution-ShareAlike 3.0)

Sam and Max

OK, so this post doesn't have any useful information whatsoever. Big Deal? Well yes, because it's got something so utterly useless that it stands out: A dog in a suit and a naked white rabbit.

More precisely, a guy in a dog suit wearing a suit carrying a rabbit.

In case you haven't noticed, over at Telltale games, they're developing a new video game series and well, these guys are simply nuts. Here's their official report from Comic-Con. Watch it, enjoy it, vote for Max!

Monday, August 6, 2007

Spore - It's not that scary!

I just finished reading an article over at Bona Fide Reviews and I simply can't keep but smiling. You should read the actual article for yourself and then consider my reply. Enjoy:

OK, let's start one by one. First of all we should clarify if we're talking directly about programming or rather some greater logic that is the basic for the whole program. In this case this is almost certainly the logic behind the programming, not the actual language itself. In fact, it's not even the logic behind the whole program: It's the logic behind one subsystem, namely the model generation.

The point is that Spore simply adds a whole new level of abstraction for generating and maintaining models. Notice that the system itself is nothing new... it has been around since the first days of game programming. But maybe it's easier to explain it using a well known example.

Consider the model generation in Half Life
You see a guy lifting his arm... what data is actually stored and which one is generated on-the-fly by Half Life, DirectX or your graphics card?

What you see is a two dimensional raster image, so does Half Life come with a image of that guy from every imaginable angle?
No, it doesn't. This would either require a huge amount of memory or limit the number of angles. However, this was done by older games like Doom to save processing power... as a result no matter from which angle you would look at a monster, it was always one of four images (Left,Right,Front,Back).

So, we've established that the guy isn't stored as a 2D raster image, so what is he made of? What data is processed into the image we see? Well, it is a vector image... an image where points and the areas between them, together with a number of parameters like the color of a area make up a description that can be used to generate a bitmap. But this doesn't really solve our problem, there are still way too many angles.

We really have to abstract some more. What data can be used that when combined with a particular angle results in a 2D vector image? You've got it: a 3D vector image! We just spread the points along an additional third axes and suddenly we can generate a 2D vector image from every imaginable point. Hurray!

But wait, the guy is lifting his arm! Uh... do we have to store a 3D vector image for every single point in time while he's lifting his arm? Well... this was done by the game on which Half Life is based (Quake) and it wasn't a very good system... In order to keep the size of all these models down, they had to remove precission resulting in a very strange effect where parts of the model would appear to change shape. Luckily, there's an alternative! We can use yet another form of abstraction! We simply divide the data up again, in this case in the static 3D vector image and a skeleton that defines which parts of the 3D vector image belong to which bone. So now we just have to store the 3D model of the skeleton and in order to for example lift his arm, we simply move the arm bone, and all points in the 3D vector image that belong to the arm bone will move the same way.

But this isn't enough! There may be hundreds of guy in the game and most of them lift their arm in a similar way. Since we seperated the skeletal animation data from the 3D vector image, we can use it for all guys, not just this one!

But we still have to define all individual states, so let's abstract some more! We can simply define a number of points along which the bone should move, and voila, we only have to save two or three states and interpolate between them.

-----------
This is where it ends for Half Life. But wait! There's more!

Unreal was one of the first games to dynamically generate images to be used as textures for the areas in a 3D vector image: They would for example specify a image and then generate a whole series of images where water was flowing across it.

Quake3 brought parametric skeletal animation to the masses. There would only be one animation for walking which was modified to make it appear as if different characters walked differently. Some would spread their legs more, others less and so on.

Others, like the famous N64 game Waveracer, would generate models for a whole see using a set of rules that formed a simplistic physics model.

And finally we see games like World of Warcraft creating a near infinite number of models by combining parts of different models.

-----------
But there's one gap. We always end up with a static model that's being deformed in various ways. And this is where Sporn offers (or appears to offer) something new. We can create arbitary models from a simple model (in this case a ball). In fact it's not new at all. We're simply add better deforming algorithms and give them more freedom in that we not only allow them to not only move existing points, but also add new ones. We add routines that we've developed to simulate physics to make it appear a if we were actually sculpting. Then we apply all the techniques mentioned before.

It's a great example of evolution, not revolution.

Friday, March 30, 2007

xmlTree - minimalistic XML processor for PHP

xmlTree is a tiny, little XML processor for PHP that doesn't even offer 10% of what the XML spec has to offer, but still manages to do almost everything a normal developer needs (and besides, it's easy to extend). It's meant for all those people that
  • Hate to use code that they cannot possibly understand
  • Prefer small libraries
  • Don't expect the XML Library to validate their data
  • Don't need the XML library to handle data that's not trustworthy
  • Don't need automatic character conversion, like " to \" or <>
So, it's really quite minimalistic. It was initially written to store configuration data for another program, but ended but managing quite a bit of the HTML code too.
Essentially, it provides the following features:
  • An XMLElement class that provides parentNode, childNodes, tagName and attributes. It also provides a value for text nodes
  • A Javascript like DOM manipulation system, featuring such gems as appendChild, setAttribute, getAttribute, removeChild, getElementsByTagName, getElementsByName,getElementById, toXML and toFile, all of which (with the exception of the last two methods) behave almost exactly like their Javascript counterparts.
  • An XMLDocument class with html, head, title and body (nothing special, but it makes life easier)
  • An XMLParser class that turns an XML string into a XMLElement tree.
You can find the source, along with some more notes here. Oh, and it's GPL too.

Labels: , ,

Tuesday, February 27, 2007

Canvas 3D Renderer updated

I've updates the Canvas 3D Renderer with new sample data, a few performance tweaks, background image support, support for colored polygons and a few tweaks here and there.
Note however that the car you see is not a sprite, it's simply an image put in front of the canvas for my amusement. So don't get confused if it doesn't behave the way you expect it to do.
Right now the sample data has around 200 faces and while the code is almost ready for shared vertices (which means that one vertex belongs to many faces, resulting in a much lower number of vertices in memory and therefore a lot less calculations) right now a face still consists of 3 vertices, meaning that it does about 500-600 rotations, projections,clipping and collision tests per frame update, with very few optimizations so far and for that the speed is (at least in my opinion) amazing.
What's interesting to me are the test results... I didn't time them, so I can't give you any numbers, but
Opera 9.1 is definitely the slowest one, but with a very steady framerate, which probably means that drawing and garbage collection are very fast (as these tend to take up a variable amount of time), but arithmetic is slow.
Firefox 2 is pretty steady as well, and a lot faster than Opera.
Firefox 3 Alpha is certainly the fastest browser, but with a very unsteady framerate. I guess the new garbage collector is causing this while drawing speed is increasing thanks to Cairo.
You can still find it at http://tapper-ware.net/canvas3d/ (Note that the background gets drawn during the first screen update after the image has loaded, so it will probably take a second or two to appear the first time you load the page. Screen updates happen whenever you move around).
P.S. I'd appreciate it if you could send me mail if you want me to answer your comments. hansschmucker at gmail dot com

Labels: , , , ,

Thursday, February 15, 2007

Real 3D Rendering right inside the browser


So far, you've always needed a plugin to even display dynamic 2D graphics, never mind 3D. So here's a 3D engine that works right inside your browser, no plugin required.



OK, first for all of you impatient guys, the controls:


  • Arrow Keys: Turn/Walk

  • PageUp/PageDown: Fly


Flying only works when you're outside the map, on the map you'll get put onto the nearest surface automatically.



Now a bit of background info:

This is a demo program for the Canvas element, which is right now being formulated as a standard over at
WHATWG.

The Canvas element is a 2D Bitmap surface to which you can draw to directly from JavaScript. So far, you couldn't
do graphics in Javascript, aside from dynamically loading different bitmaps from the server. The Canvas element closes
that gap. Now you can actually draw arbitrary shapes, without loading anything from the Server.

For that purpose, the Canvas element provides an API that allows you to draw vector shapes and bitmaps.



The target for Canvas is to not only provide a 2D API, but also one for 3D based on OpenGLes. Sadly, this API
hasn't yet arrived, and it looks like it will take some time until browsers support it, but the 2D API is here and it's
working just fine in anything but InternetExplorer, and even for that Google provides wrapper code free of charge
(note however that this wrapper code isn't being used here, so you'll need either Firefox 2+ or Opera 9+, Safari hasn't
been tested). So I decided to write a little 3D Renderer myself. It's not complex, it's not finished, but what the hell:
it works. While this isn't the first attempt to do this
(Canvascape comes to mind),
it is as far as I know the first one to try real 3D instead of Doom-style pseudo 3D. In fact, this demo loads a standard
Alias Wavefront OBJ file, and builds the model from the triangles it finds in there.



So what does this demo do? Well, basically this:


  • Load a model

  • Set up controls to modify a view object

  • Find the nearest triangle below the player

  • Move the player down to that triangle

  • Rotate the model

  • Clip it against Z=0 so you only render what's in front of you

  • Split partially visible triangles against Z=0

  • Project all vertices, so that they get smaller the farther away they are

  • Draw them, with the distance dictating the color


It's a bit more complex, but these are the important parts.



So what do I want to do with this? Well, eventually it should becomes a little racing game. Remember ReVolt?
Something like that and from the performance I get so far, it seems possible.

Which brings me to the needed optimizations:

I've got absolutely no idea why, but it seems like all Canvas implementations do pixel based clipping against
the drawing window, instead of shape-based clipping... essentially that means that drawing a 1000x1000 pixel
shape, it takes 100 times as long as drawing a 100x100 pixel shape, even when the Canvas is only 20x20 pixels
in size.

Then the game needs a BSP tree because JavaScript is too slow to calculate visibility for every triangle in
realtime... so there has to be a structure that dictates that from position 1,1,1 faces 2,5,8,10 are visible, while
from position 5,6,12 faces 3,15,33,110 are visible.

Then we need a real colission detection for a meaningfull game and support for sprites.
There will probably be a 1000 other things to do, but that's what I have in mind now.

Oh, and forget about textures... it's just not possible at descent speed.



Notes. The code is copyrighted Hans Schmucker and licensed und the GPL v2.5

Monday, February 5, 2007

Sudoku! (Update: Now with 1000 puzzles)

OK, so yesterday evening I started working on a new Javascript minigame: Sudoku.
I know what you're going to say: there already are way too many Sudoku games around. And you're absolutely right.
Problem is, there are very few good games around, and even less that run in your browser and almost none that require no plugins.

There's already a first Alpha version available here (but with just a single puzzle):
Here!

The feature list is already longer than for most other Sudoku games:
  1. Use the buttons at the bottom to add notes to the selected field.
  2. Use the buttons at the right to confirm a number.
  3. Use the "?" to get all notes automatically.
  4. You can't confirm numbers that collie with other numbers in the field, however you can enter numbers that are simply wrong.
So what's still missing (aside from a new UI):
  • Automatic Solver
  • Generator
  • Tabs for different versions of the same puzzle
  • True handwritten notes
  • Menu to enable/disable solvers.
Did I forget anything? Tell me!

Update:
Now there are 1000 new puzzles available. While there is still no generator in this, I have instead opted to instead create a converter for the files generated by QQwing, A free Sudoku generator published as OpenSource. Now, on launch the game will select a random number between 0 and 1000 and load the level with that number. However there are no difficulty levels yet: While QQwing supports this, it is not being used yet. All levels are difficulty "Expert".

Labels: , , ,

Thursday, January 25, 2007

Tutorial for native ARM PalmOS applications using PRC-Tools

Writing applications for PalmOS using native ARM code, especially using only free tools is something that seems impossible to most people. Well, with this tutorial I aim to prove them wrong: the aim is create a simple breakout tool using only free tools. It's primarily aimed at people who have some experience with the programming language C, but have never developed for PalmOS. However if you have some understanding of how a computer works, you should be able to complete it without too many difficulties as well.


Basically, this document is divided into the following parts:

  1. Tools Setup

    1. Cygwin

    2. PRC-Tools

    3. PalmOS SDK

    4. PEAL

    5. PARM Lib

    6. pilrc


The breakout game will be posted lateron :)

Tools

Naturally, the first thing you want to do is set up all the tools you'll need to compile your code into a PalmOS application, While this is a bit of a task, most of it is pretty straightforward, the most difficult part is actually knowing what you are going to need:

Cygwin (and PRC-Tools)

All the tools you are going to use are actually Linux tools, so the first thing you're going to need is a Linux-like environment. Of course you could install Linux, but of course that's not for everybody.

Cygwin is basically an environment that translates Linux commands into their Windows counterparts, so that Linux apps can run under Windows. Think of it as a Linux emulator (Before the more experienced users start crying: I know that's not the way it works, but for our purposes this comparison is sufficient).

Installation is very simple, just download the installer from http://www.cygwin.com/ (“Install or update now! (using setup.exe)”) and run it. Chose the following options:

“Next” ->

“Install from the Internet”, “Next” ->

“Root Directory” (Enter the path where you want to install Cygwin), “Install for All Users”, “Default Text File Type Unix / binary”, “Next” ->

“Local Package Directory” (Enter path where downloaded files should be saved, so you can reuse them when reinstalling Cygwin), “Next” ->

“Direct Connection” or whatever you need to get a connection to the internet, “Next” ->

Enter “http://prc-tools.sourceforge.net” into the “User URL:” field, press “Add”, Locate “http://prc-tools.sourceforge.net” in the list, click to select, locate a different mirror, for example “http://ftp.heanet.ie” is pretty reliable, hold down “CTRL” while selecting it, check if both “http://prc-tools.sourceforge.net” and “http://ftp.heanet.ie” are selected, “Next” ->

Click on the “+” in front of “Devel” and find the packages “GCC”, “Make”, “PRC-Tools” and “PRC-Tools-ARM”. Click on the word “Skip” next to them until it says “install”or the latest version number (Don't install “pilrc”), “Next” ->

“Installation Complete”



Now the compiler is installed and ready.

PalmOS SDK

Unfortunately, you need a little more than just a compiler to create a working program. You also need some libraries that allow you access to the PalmOS system internals. These libraries are contained in the PalmOS SDK. To get it, you have to register at http://www.developerpavilion.com/. After you have registered, sign in and go to “Palm OS Developer Tools“. Chose “Core Palm OS SDK” and finally download “Palm OS Garnet SDK (68K) R3 PRC tools Generic UNIX”. Don't worry about it saying “UNIX”, that includes Cygwin as well. Create a new directory inside your Cygwin installation and name it “PalmDev”. Save the file to that directory. (While you're there, it's probably a good idea to also get the PalmOS reference, companions and simulator)

Open the Cygwin Bash Shell from your Start Menu and perform the following actions:

cd /PalmDev/

tar -xzf palmos-sdk-5.0r3-1.tar.gz

palmdev-prep



(Of course, if the archive has a different file name, use that instead of “palmos-sdk-5.0r3-1.tar.gz”)

After running palmdev-prep you should get something like this:

Checking SDKs in /PalmDev

sdk-5r3 headers in 'include', libraries in 'lib'

When GCC is given no -palmos options, SDK '5r3' will be used by default

Writing SDK details to configuration files...

...done



OK, so now the SDK is installed and configured as the default option for the PalmOS compiler. Now you could already start writing code for the 68k plattform. But we want to do a little more than that.

PEAL

Problem is that the arm-palmos-gcc compiler, aside from not working well with the SDK, is that it is pretty limited in what C features it supports. Especially global variables are a problem and this is where PEAL comes in. PEAL is a little parser that relocates data so that global variables work. To install it, just download the tar.gz archive from http://www.sealiesoftware.com/peal/ and place it in PalmDev as well. Extract it with

tar -xzf peal-2005_4_14.tar.gz

(Or whatever you named that file).

This will extract peal and create a directory named something like “peal-2005_4_14” to rename it to just “peal” enter

mv peal-2005_4_14 peal

Now, change to that directory with

cd peal

And go to the postlink directory

cd postlink

Now all you've got to do is compiling PEAL. Just type in

make

You'll get a few warnings, but after a few seconds you'll get back to the shell.

Enter

./peal-postlink

and you get the help message for PEAL.

PARM

Now we have to overcome the final (and most difficult) shortcoming of arm-palmos-gcc: It's inability to communicate with PalmOS. PARM does some magic to do this... it's rather complicated and you actually don't need to understand it, so there's no point trying to explain it. Installation is very simple, just download http://www.tapper-ware.net/files/PARM.zip and extract it to your PalmDev directory. It will create a PARM directory containing the necessary files and an example. Change to the example directory with

cd /PalmDev/PARM/example/

The sample code is contained in main.c, make68k.sh contains the information to build the application so that the PalmOS simulator can run it, while makepno.sh compiles the real ARM application. Try it. Run

./make68k.sh

and a main68k.prc file should appear in the directory. Drag it onto the simulator and run “MyBreakout”. It will display an empty screen and when you click somewhere it will draw “Hello World” at that point.

Now try to build the native application. Run

./makepno.sh

and it will first output a warning message

In file included from ../../pnotest.c:27:

../../pace_gen.c: In function `StrPrintF':

../../pace_gen.c:133: warning: dereferencing type-punned pointer will break stri

ct-aliasing rules

Just ignore it, that's normal. You'll get it every time you compile something, there's nothing wrong with that. A mainpno.prc file should appear that's identical to main68k.prc, but contains fast, native ARM code. Hotsync it and see if it works. If makepno.sh throws any more errors than it probably can't find some file, because you placed it somewhere other than the default location. In that case you need to edit the make* scripts. You really only need a simple text-editor for that, but it has to support UNIX-style linebreaks... that's something pretty much any editor besides notepad can do, but my favourite editor is SciTE ( http://scintilla.sourceforge.net/SciTEDownload.html ), because it requires no installation and has pretty good source highlighting for about any programming language I know. Open makepno.sh in the editor of your choice and you'll see the script's source. The most common problem is that you installed PEAL somewhere else than /PalmDev/peal . Just look through it and most likely, you'll spot the culprit within seconds.

Pilrc

Pilrc is a resource editor for PalmOS. You'll need it to add icons, forms, bitmaps and so on to your PRC file. Just download pilrc-3.2-win32.zip from http://sourceforge.net/project/showfiles.php?group_id=7404 and extract it to your \windows\system32\ directory. That's it :) I'm not going to give you a sample now, but we're going to need it when we do the breakout game next time.



See you then :)

Hans







Wednesday, January 24, 2007

T8Launcher 0.4 with new layout engine and button input

This release features en entirely new layout engine, which will soon allow T8launcher to work on any ARM PalmOS device, even on Cliés with their hybrid Sony Hires/Garnet Hires API. However for now it still only works on the Zodiac as I have yet to modify the screen setup to handle different screens correctly. Also, the portrait skin is still incomplete and the square aspect ratio skin doesn't even exist.
The most notable improvement in this release is the ability to enter text with the buttons and joystick:

To enter text with the joystick, just press it, move it to the desired position (let's say top-left for "abc" or center for "mn") and release it again. While you're pressing the joystick, the letters that you would enter if you released the joystick will light up.

Another way are the 4 colored buttons on the Zodiac. Just press the button(s) that point in the correct direction. For example Blue and Red (at the same time) for "abc", Red for "def" and so on. To enter "no" you have to press (at least) two opposite buttons, for example blue and green. Pressing three or four buttons at once has the same affect.

The other functions are also available: Press "Home" for Backspace, "Func" to cycle the list and one of the triggers to launch the selected application.

While the joystick feels more natural for inputing text, the buttons are actually a lot more precise, so I'd recommend using this method for text input.
  • New layout engine with skining
  • Added wrappers for various HiRes APIs (not used yet)
  • Added partially complete 320x480 skin
  • Added button input
You can download it here:

Download:

Labels: , ,

Saturday, January 20, 2007

T8Launcher updated to 0.3

This is mainly a bugfixing release, but it also features a smaller footprint:
  • Fixed a problem where database-handles wouldn't get released, leading to a drawing problem with EDGE.
  • Fixed the problem with long application names "leaking" into the "abc1" button.
  • Optimized bitmaps for compression, bringing the filesize down to 213kb.
You can download it here:

Download:

Labels: , ,

Thursday, January 18, 2007

T8Launcher updated to 0.2

OK, it seems like the main problem was that the interface wasn't informative enough, so the changelog is pretty UI-centric:
  • Made text transparent, instead of white background
  • Added label "Launch" to launch button
  • Added label "Next App" to cycle apps button
  • Added label "Backspace" to delete button
  • Added count of remaining matches to cycle apps button (including label "Remaining Matches in List:")
  • Added input string position to delete button (including label "Number of entered Chars:")
  • When there's no match for the current query string, display message and delete last character.
  • Fixed rotation after exiting from Portrait app
  • Don't display hidden apps anymore
You can download it here:

Download:

Labels: , ,

Tuesday, January 16, 2007

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.

Labels: , ,

Monday, January 1, 2007

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 480x320 resolution.

That's right: 480x320, not 320x200 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).

Labels: , , , , ,

Monday, December 18, 2006

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.

Saturday, December 9, 2006

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.

Labels: , , ,