<?xml version='1.0' encoding='UTF-8'?><rss xmlns:atom='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' version='2.0'><channel><atom:id>tag:blogger.com,1999:blog-9178810892351172948</atom:id><lastBuildDate>Mon, 08 Sep 2008 01:05:06 +0000</lastBuildDate><title>Tapperware - Tapping into Mobile Technology</title><description>A blog about Mobile Technology, Politics as far as they affect technological development and just random gibberish.</description><link>http://www.tapper-ware.net/</link><managingEditor>noreply@blogger.com (Hans Schmucker)</managingEditor><generator>Blogger</generator><openSearch:totalResults>24</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-8079362347104742891</guid><pubDate>Mon, 08 Sep 2008 00:56:00 +0000</pubDate><atom:updated>2008-09-08T03:05:06.233+02:00</atom:updated><title>Please, dear god, KILL JSCRIPT!</title><description>Yeah, this is one of those "Oh for crying out loud" posts. Right now I'm working on implementing ECMA 262 in Javascript... and JScript, Microsoft's piece of junk runtime that "powers" Internet Explorer. OK, so I was doing a little testing using non-English variable names. I wanted to support at least such a basic feature exactly like the spec says, but as it turns out this will be a lot more complicated than I imagined. Basically, JScript doesn't care about variable names. x³ is accepted as a valid variable name by JScript, while the spec clearly states that only numbers that look like letters (like fi) are valid as parts of variable names... so I'm left manually parsing variable names, instead of just parsing for "stoppers" (linebreaks, dots, "=" and so on). If you want to see what that looks like, here's the RegExp for parsing a single character. A word of warning thow. It might scare you. I know it scares me and I'm the one who compiled that darn thing from the UTF-16 character table. &lt;a href="http://pastebin.mozilla.org/530081"&gt;Here's the link&lt;/a&gt;</description><link>http://www.tapper-ware.net/2008/09/please-dear-god-kill-jscript.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-2718096814234300470</guid><pubDate>Tue, 02 Sep 2008 20:39:00 +0000</pubDate><atom:updated>2008-09-03T00:19:36.706+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>browsers</category><category domain='http://www.blogger.com/atom/ns#'>google</category><title>Google Chrome? Good for some people, not good enough for me.</title><description>&lt;div style="text-align: left;"&gt;UPDATE:&lt;br /&gt;A few people have since pointed out that there are developer tools available in the "page" menu. Sorry, it wasn't obvious to me. So cross out the points below concerning the absence of such tools.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Concerning &lt;a href="http://googleblog.blogspot.com/2008/09/google-chrome-now-live.html"&gt;Google Chrome&lt;/a&gt;,&lt;br /&gt;&lt;/div&gt;Right now, Blogs all over the world are reporting about the great new browser Google has and I too decided to take a look. After all, it's Google we're talking about here, so it has to be good.&lt;br /&gt;&lt;br /&gt;And it is, kinda. Google is trying to create a browser for the "casual" crowd. People who spend less than an hour a day using the internet, people who don't have a lot of tabs open and who freak out when a program crashes. People who don't have friends who can help them set up their computer and are therefore stuck with Microsoft's slow and buggy Internet Explorer. And for that purpose, Chrome is actually quite good.&lt;br /&gt;&lt;br /&gt;Let's start with the installation. Run, say whether you want to import your Internet Explorer favorites  (it didn't even give me an option to import my Firefox bookmarks). Done. It's really that simple and straightforward. Of course I'd like to have more options, but I'm not really the one Google is trying to win over, so that's OK.&lt;br /&gt;&lt;br /&gt;Then it starts. And my first thoughts are "Man, this is ugly". Where other browsers try to look like native applications, Google has chosen the opposite route. The buttons on the top look a bit like Vista's, but that's about it (besides, I'm not using Vista, so it would be the wrong OS anyway). Everything else is in a Google typical gray/blue theme that looks more like a webpage than an application. The fact that it integrates poorly with the OS alone is almost a dealbreaker for me, but once again, it might actually appeal to people who do little enough with their PC that they value glamour over consistency. However, it seems like usability was not really that interesting to the Google folks either: The grey/light blue color combination provides little contrast and my first few clicks where actually attempts to click on the nearly invisible scrollbar.&lt;br /&gt;&lt;br /&gt;Next step. The welcome page has opened and greats me with what to expect the next time I come here (a list of most used pages). I already know that, but decide to take a look at the help anyway, which turns out to be a little page with a few UI tips. Sadly, the navigation breaks and pressng "back" doesn't work as expected as it only changes the title of the page to "Untitled". I have to admit, I expected a bit more polish here and while it isn't really a dramatic bug, it's not a good thing to present the user with it on his first launch.&lt;br /&gt;&lt;br /&gt;The basic browsing functions work fine, after all WebKit has been used a few times before and by now is pretty good. The Javascript engine also is almost as fast as promised and generally does a good job. Nothing to complain about here.&lt;br /&gt;&lt;br /&gt;So I decide to take a look at the taskmanager to see how Google's idea to seperate the tabs into individual processes has worked out. Not to well for me as it turns out. Chrome is using 267MB of memory right now, while Firefox with the same pages open uses 186MB. Again, Chrome turned out to be very bad for my habbits... I can't even see any of my tab's titles anymore, because there's no tabbar scrolling. But would your typical "casual" surfer open 30+ tabs at once? Probably not. Again, a major issue for me turned out to be just fine for the target audience.&lt;br /&gt;&lt;br /&gt;And so it goes on and on. No addons, no error console, no developer tools, nothing that a casual user won't miss. And that's really all there is to it. If you want just a simple browser, then this is fine.&lt;br /&gt;&lt;br /&gt;The only question that remains for me: Why then not use Safari itelf, instead of Google's version?&lt;br /&gt;&lt;br /&gt;Oh and one last thing. Whoever wrote that comic didn't do Google a favour. Because to me, this "that's how we do it and that's the only right way to do it" talking sounds just terrible. Mockery doesn't really inspire sympathy and when a friend asks me "which browser should I install?" it might be this bit that keeps me from saying "Try Google Chrome".</description><link>http://www.tapper-ware.net/2008/09/google-chrome-good-for-some-people-not.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-4450684463709654133</guid><pubDate>Wed, 27 Aug 2008 23:03:00 +0000</pubDate><atom:updated>2008-08-28T01:08:47.195+02:00</atom:updated><title>Accelerating per-pixel collisions in Canvas</title><description>For the impatient ones:&lt;br /&gt;Main demo HTML:&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/index.xhtml"&gt;index.xhtml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I think the code could be interesting for people working on highly interactive content for decent browsers (yes, that excludes InternetExplorer. There's no way to work around this short of offering Canvas as a plugin).&lt;br /&gt;&lt;br /&gt;The only way so far to use per-pixel collisions with Canvas is using getImageData, which has a terrible overhead and I thought I could accelerate the whole thing by using bitmap functions to pre-filter the data. Right now it is meant for colliding a map with a sprite, but with a bit of work it could also be used to colliding two sprites. Basically it works like this:&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Calculate size of the rotated and scaled sprite.&lt;/li&gt;&lt;li&gt;Create a canvas of this size&lt;/li&gt;&lt;li&gt;Load the map file and blit it to that canvas.&lt;/li&gt;&lt;li&gt;Load the sprite and blit it to the same canvas, keeping only parts where the previous content and the sprite overlap.&lt;/li&gt;&lt;li&gt;Scale the canvas down to 1/16 of it's original size) (technically 1/256 should also work, but it seems that the scaling starts skipping pixels then).&lt;/li&gt;&lt;li&gt;Convert the downscaled image to a pixel array.&lt;/li&gt;&lt;li&gt;Check the alpha channel of the pixel array. If any pixel has an alpha value &gt;0, we have a colission.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Using this optimization my PC (1.8Ghz) is able to calculate around 3000 16x16 sprite collisions per second, which should be plenty for any normal game.&lt;br /&gt;&lt;br /&gt;I've written a little demo, where 100 Tentacles invade my hometown (Mannheim). With 100 collisions, there's even time for a fancy cloud shadow effect :) . Note that they don't collide with each other. While this is possible (actually, the code is already in there, you just have to remove the comments) it slows the whole thing down with little noticeable effect.&lt;br /&gt;So far I've tested it in today's Minefield build and Opera 9.50. While it does work in Opera, it's too slow for practical use. In Minefield it works with or without tracing, but with negligible difference as most work is done natively by the image functions anyway. Safari fails totally for me, but then again Safari never worked properly on my system anyway (I can't get to the error console. Yes I have the menu enabled, but when I select it, nothing happens).&lt;br /&gt;&lt;br /&gt;The source for the main classes is GPLed, but the main file intentionally isn't, because the map image is provided by GoogleMaps and so only licensed under "fair use". Likewise, the tentacle is a redrawn character from Day of the Tentacle.&lt;br /&gt;&lt;br /&gt;GPLed sources:&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/classes/$js.js"&gt;$js.js&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/classes/CanvasCollision.js"&gt;CanvasCollision.js&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/classes/Entity.js"&gt;Entity.js&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/classes/Crowd.js"&gt;Crowd.js&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/main.js"&gt;main.js&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Main demo HTML:&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/index.xhtml"&gt;index.xhtml&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The individual images used in this demo:&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/map_walkable.png"&gt;map_walkable.png&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/map.png"&gt;map.png&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/clouds.png"&gt;clouds.png&lt;/a&gt;&lt;br /&gt;&lt;a href="http://tapper-ware.net/devel/js/JS.Collision/sprite.png"&gt;sprite.png&lt;/a&gt;</description><link>http://www.tapper-ware.net/2008/08/accelerating-per-pixel-collisions-in.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-5322945091493673165</guid><pubDate>Fri, 18 Jan 2008 19:21:00 +0000</pubDate><atom:updated>2008-01-18T20:58:29.723+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>ajax</category><category domain='http://www.blogger.com/atom/ns#'>browsers</category><title>Secure web applications - using JS to create a new web language</title><description>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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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".&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Let's tackle these questions one by one:&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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).</description><link>http://www.tapper-ware.net/2008/01/secure-web-applications-using-js-to.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-8939837912478291799</guid><pubDate>Sun, 13 Jan 2008 22:31:00 +0000</pubDate><atom:updated>2008-01-14T00:08:27.844+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>politics</category><title>If I had a Hammer OR Why RFID in passports is a really bad idea...</title><description>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.&lt;br /&gt;&lt;br /&gt;The more important question is why should I do it? Well there are a couple of reasons, so let's make a list:&lt;br /&gt;&lt;br /&gt;Let's start with the basic problems of any encrypted data:&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;But are there other scenarios where the chip could reveal your presence. Even if the encryption was not compromised?&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;And this would only be the "normal", "marketing" way of analysing your data. Criminals are much more inventive...&lt;br /&gt;&lt;br /&gt;I'm not asking you to do anything but think about it how your privacy gets a beating with RFID passports.</description><link>http://www.tapper-ware.net/2008/01/if-i-had-hammer-or-why-rfid-in.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-2407505003547623955</guid><pubDate>Sun, 26 Aug 2007 16:44:00 +0000</pubDate><atom:updated>2007-08-26T18:47:52.904+02:00</atom:updated><title>CSI moves to Origo</title><description>CSI, the Javascript client side inclusion library, is moving to a &lt;a href="http://csi.origo.ethz.ch/"&gt;new home&lt;/a&gt; over at &lt;a href="http://origo.ethz.ch/"&gt;Origo&lt;/a&gt;... if you're interested in joining the project, just create an account over at &lt;a href="http://origo.ethz.ch/"&gt;Origo&lt;/a&gt; and &lt;a href="mailto:hansschmucker@gmail.com"&gt;drop me a line&lt;/a&gt;.</description><link>http://www.tapper-ware.net/2007/08/csi-moves-to-origo.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-5554374009462195141</guid><pubDate>Sun, 26 Aug 2007 16:41:00 +0000</pubDate><atom:updated>2007-08-26T18:44:34.644+02:00</atom:updated><title>You've gotta love some quotes</title><description>&lt;p&gt;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.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;From: Bill Gates&lt;br /&gt;       Sent: Saturday, December 5 1998&lt;br /&gt;       To: Bob Muglia, Jon DeVann, Steven Sinofsky&lt;br /&gt;       Subject : Office rendering&lt;/p&gt;       &lt;p&gt;&lt;em&gt;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.&lt;/em&gt;&lt;/p&gt;       &lt;p&gt;&lt;em&gt;We have to stop putting any effort into this and make sure          that Office documents very well depends on PROPRIETARY IE capabilities.&lt;/em&gt;&lt;/p&gt;       &lt;p&gt;&lt;em&gt;Anything else is suicide for our platform. This is a case          where Office has to avoid doing something to destroy Windows.&lt;/em&gt;&lt;/p&gt;       &lt;p&gt;&lt;em&gt;I would be glad to explain at a greater length.&lt;/em&gt;&lt;/p&gt;       &lt;p&gt;&lt;em&gt;Likewise this love of DAV in Office/Exchange is a huge          problem. I would also like to make sure people understand this as well.&lt;/em&gt;&lt;/p&gt;</description><link>http://www.tapper-ware.net/2007/08/youve-gotta-love-some-quotes.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-3563503043526276226</guid><pubDate>Mon, 20 Aug 2007 19:51:00 +0000</pubDate><atom:updated>2007-08-20T22:25:40.055+02:00</atom:updated><title>CSI - Client Side Includes</title><description>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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Enter CSI - Client Side Includes.&lt;br /&gt;&lt;br /&gt;CSI is something in between a library and a framework. It's tiny (the core is &lt;2k uncompressed) and requires only minimal modifications to your code.&lt;br /&gt;&lt;br /&gt;For more details (as well as a demo) and the download, check &lt;a href="http://www.tapper-ware.net/devel/js/csi/csi.htm"&gt;here&lt;/a&gt;.</description><link>http://www.tapper-ware.net/2007/08/csi-client-side-includes.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-5998872793312681811</guid><pubDate>Sun, 19 Aug 2007 18:18:00 +0000</pubDate><atom:updated>2007-08-19T20:28:39.772+02:00</atom:updated><title>Smoothly fading slideshows and hover buttons</title><description>This was done per request and while the code is not really beautiful, it works just fine.&lt;br /&gt;&lt;br /&gt;"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.&lt;br /&gt;&lt;br /&gt;See it in action, along with a short introduction &lt;a href="http://www.tapper-ware.net/devel/js/fade/fade.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I'd love to hear some &lt;a href="mailto:hansschmucker@gmail.com"&gt;feedback&lt;/a&gt;, too. :)&lt;br /&gt;&lt;br /&gt;(License is CC Attribution-ShareAlike 3.0)</description><link>http://www.tapper-ware.net/2007/08/smoothly-fading-slideshows-and-hover.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-781661594075301555</guid><pubDate>Sun, 19 Aug 2007 16:17:00 +0000</pubDate><atom:updated>2007-08-19T18:23:35.174+02:00</atom:updated><title>Sam and Max</title><description>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.&lt;br /&gt;&lt;br /&gt;More precisely, a guy in a dog suit wearing a suit carrying a rabbit.&lt;br /&gt;&lt;br /&gt;In case you haven't noticed, over at &lt;a href="http://www.telltalegames.com/"&gt;Telltale games&lt;/a&gt;, they're developing a new video game series and well, these guys are simply nuts. Here's their &lt;a href="http://www.telltalegames.com/community/blogs/id-244"&gt;official report&lt;/a&gt; from Comic-Con. Watch it, enjoy it,&lt;a href="http://www.maxforpresident.org/"&gt; vote for Max!&lt;/a&gt;</description><link>http://www.tapper-ware.net/2007/08/sam-and-max.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-5291611059812074116</guid><pubDate>Sun, 05 Aug 2007 23:30:00 +0000</pubDate><atom:updated>2007-08-06T01:34:50.656+02:00</atom:updated><title>Spore - It's not that scary!</title><description>I just finished reading an article over at &lt;a href="http://www.bonafidereviews.com/article.php?id=224"&gt;Bona Fide Reviews&lt;/a&gt; and I simply can't keep but smiling. You should read the &lt;a href="http://www.bonafidereviews.com/article.php?id=224"&gt;actual article&lt;/a&gt; for yourself and then consider my reply. Enjoy:&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;Consider the model generation in Half Life&lt;br /&gt;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?&lt;br /&gt;&lt;br /&gt;What you see is a two dimensional raster image, so does Half Life come with a image of that guy from every imaginable angle?&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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!&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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!&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;-----------&lt;br /&gt;This is where it ends for Half Life. But wait! There's more!&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;And finally we see games like World of Warcraft creating a near infinite number of models by combining parts of different models.&lt;br /&gt;&lt;br /&gt;-----------&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;It's a great example of evolution, not revolution.</description><link>http://www.tapper-ware.net/2007/08/spore-its-not-that-scary.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-6899131147261650456</guid><pubDate>Fri, 30 Mar 2007 14:24:00 +0000</pubDate><atom:updated>2007-03-30T18:28:58.162+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>ajax</category><category domain='http://www.blogger.com/atom/ns#'>browsers</category><category domain='http://www.blogger.com/atom/ns#'>php</category><title>xmlTree - minimalistic XML processor for PHP</title><description>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 &lt;ul&gt;&lt;li&gt;Hate to use code that they cannot possibly understand&lt;/li&gt;&lt;li&gt;Prefer small libraries&lt;/li&gt;&lt;li&gt;Don't expect the XML Library to validate their data&lt;/li&gt;&lt;li&gt;Don't need the XML library to handle data that's not trustworthy&lt;/li&gt;&lt;li&gt;Don't need automatic character conversion, like " to \" or &lt;&gt;&lt;/li&gt;&lt;/ul&gt;    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.&lt;br /&gt;  Essentially, it provides the following features:    &lt;ul&gt;&lt;li&gt;An XMLElement class that provides parentNode, childNodes, tagName and attributes. It also provides a value for text nodes&lt;/li&gt;&lt;li&gt;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.&lt;/li&gt;&lt;li&gt;An XMLDocument class with html, head, title and body (nothing special, but it makes life easier)&lt;/li&gt;&lt;li&gt;An XMLParser class that turns an XML string into a XMLElement tree.&lt;/li&gt;&lt;/ul&gt;You can find the source, along with some more notes &lt;a href="http://www.tapper-ware.net/devel/php/xmlTree/xmlSample.php"&gt;here&lt;/a&gt;. Oh, and it's GPL too.</description><link>http://www.tapper-ware.net/2007/03/xmltree-minimalistic-xml-processore-for.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-7584122610552321830</guid><pubDate>Tue, 27 Feb 2007 04:42:00 +0000</pubDate><atom:updated>2007-02-27T06:07:08.775+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>games</category><category domain='http://www.blogger.com/atom/ns#'>ajax</category><category domain='http://www.blogger.com/atom/ns#'>browsers</category><category domain='http://www.blogger.com/atom/ns#'>mozilla</category><title>Canvas 3D Renderer updated</title><description>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.&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;What's interesting to me are the test results... I didn't time them, so I can't give you any numbers, but&lt;br /&gt;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.&lt;br /&gt;Firefox 2 is pretty steady as well, and a lot faster than Opera.&lt;br /&gt;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.&lt;br /&gt;You can still find it at &lt;a onclick="return top.js.OpenExtLink(window,event,this)" href="http://tapper-ware.net/canvas3d/" target="_blank"&gt;http://tapper-ware.net/canvas3&lt;wbr&gt;d/&lt;/a&gt; (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).&lt;br /&gt;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</description><link>http://www.tapper-ware.net/2007/02/canvas-3d-renderer-updated.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-6686779802843610423</guid><pubDate>Wed, 14 Feb 2007 23:55:00 +0000</pubDate><atom:updated>2007-02-15T00:58:50.264+01:00</atom:updated><title>Real 3D Rendering right inside the browser</title><description>&lt;p&gt;&lt;br /&gt;   So far, you've always needed a plugin to even display dynamic 2D graphics, never mind 3D. So &lt;a href="http://tapper-ware.net/canvas3d/"&gt;here&lt;/a&gt;'s a 3D engine that works right inside your browser, no plugin required.&lt;br /&gt;  &lt;/p&gt;&lt;br /&gt;  &lt;p&gt;&lt;br /&gt;   OK, first for all of you impatient guys, the controls:&lt;br /&gt;   &lt;ul&gt;&lt;br /&gt;    &lt;li&gt;Arrow Keys: Turn/Walk&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;PageUp/PageDown: Fly&lt;/li&gt;&lt;br /&gt;   &lt;/ul&gt;&lt;br /&gt;   Flying only works when you're outside the map, on the map you'll get put onto the nearest surface automatically.&lt;br /&gt;  &lt;/p&gt;&lt;br /&gt;  &lt;p&gt;&lt;br /&gt;   Now a bit of background info:&lt;br /&gt;&lt;br /&gt;   This is a demo program for the Canvas element, which is right now being formulated as a standard over at&lt;br /&gt;   &lt;a href="http://www.whatwg.org/specs/web-apps/current-work/#the-canvas"&gt;WHATWG&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;   The Canvas element is a 2D Bitmap surface to which you can draw to directly from JavaScript. So far, you couldn't&lt;br /&gt;   do graphics in Javascript, aside from dynamically loading different bitmaps from the server. The Canvas element closes&lt;br /&gt;   that gap. Now you can actually draw arbitrary shapes, without loading anything from the Server.&lt;br /&gt;&lt;br /&gt;   For that purpose, the Canvas element provides an API that allows you to draw vector shapes and bitmaps.&lt;br /&gt;  &lt;/p&gt;&lt;br /&gt;  &lt;p&gt;&lt;br /&gt;   The target for Canvas is to not only provide a 2D API, but also one for 3D based on OpenGLes. Sadly, this API&lt;br /&gt;   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&lt;br /&gt;   working just fine in anything but InternetExplorer, and even for that Google provides wrapper code free of charge&lt;br /&gt;   (note however that this wrapper code isn't being used here, so you'll need either Firefox 2+ or Opera 9+, Safari hasn't&lt;br /&gt;   been tested). So I decided to write a little 3D Renderer myself. It's not complex, it's not finished, but what the hell:&lt;br /&gt;   it works. While this isn't the first attempt to do this&lt;br /&gt;   (&lt;a href="http://www.abrahamjoffe.com.au/ben/canvascape/"&gt;Canvascape&lt;/a&gt; comes to mind),&lt;br /&gt;   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&lt;br /&gt;   Alias Wavefront OBJ file, and builds the model from the triangles it finds in there.&lt;br /&gt;  &lt;/p&gt;&lt;br /&gt;  &lt;p&gt;&lt;br /&gt;   So what does this demo do? Well, basically this:&lt;br /&gt;   &lt;ul&gt;&lt;br /&gt;    &lt;li&gt;Load a model&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Set up controls to modify a view object&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Find the nearest triangle below the player&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Move the player down to that triangle&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Rotate the model&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Clip it against Z=0 so you only render what's in front of you&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Split partially visible triangles against Z=0&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Project all vertices, so that they get smaller the farther away they are&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;Draw them, with the distance dictating the color&lt;/li&gt;&lt;br /&gt;   &lt;/ul&gt;&lt;br /&gt;   It's a bit more complex, but these are the important parts.&lt;br /&gt;  &lt;/p&gt;&lt;br /&gt;  &lt;p&gt;&lt;br /&gt;   So what do I want to do with this? Well, eventually it should becomes a little racing game. Remember ReVolt?&lt;br /&gt;   Something like that and from the performance I get so far, it seems possible.&lt;br /&gt;&lt;br /&gt;   Which brings me to the needed optimizations:&lt;br /&gt;&lt;br /&gt;   I've got absolutely no idea why, but it seems like all Canvas implementations do pixel based clipping against&lt;br /&gt;   the drawing window, instead of shape-based clipping... essentially that means that drawing a 1000x1000 pixel&lt;br /&gt;   shape, it takes 100 times as long as drawing a 100x100 pixel shape, even when the Canvas is only 20x20 pixels&lt;br /&gt;   in size.&lt;br /&gt;&lt;br /&gt;   Then the game needs a BSP tree because JavaScript is too slow to calculate visibility for every triangle in&lt;br /&gt;   realtime... so there has to be a structure that dictates that from position 1,1,1 faces 2,5,8,10 are visible, while&lt;br /&gt;   from position 5,6,12 faces 3,15,33,110 are visible.&lt;br /&gt;&lt;br /&gt;   Then we need a real colission detection for a meaningfull game and support for sprites.&lt;br /&gt;   There will probably be a 1000 other things to do, but that's what I have in mind now.&lt;br /&gt;&lt;br /&gt;   Oh, and forget about textures... it's just not possible at descent speed.&lt;br /&gt;  &lt;/p&gt;&lt;br /&gt;  &lt;p&gt;&lt;br /&gt;   Notes. The code is copyrighted Hans Schmucker and licensed und the GPL v2.5&lt;br /&gt;  &lt;/p&gt;</description><link>http://www.tapper-ware.net/2007/02/real-3d-rendering-right-inside-browser.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-3729711138910459976</guid><pubDate>Mon, 05 Feb 2007 17:46:00 +0000</pubDate><atom:updated>2007-02-05T22:27:42.053+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>games</category><category domain='http://www.blogger.com/atom/ns#'>ajax</category><category domain='http://www.blogger.com/atom/ns#'>browsers</category><title>Sudoku! (Update: Now with 1000 puzzles)</title><description>OK, so yesterday evening I started working on a new Javascript minigame: Sudoku.&lt;br /&gt;I know what you're going to say: there already are way too many Sudoku games around. And you're absolutely right.&lt;br /&gt;Problem is, there are very few good games around, and even less that run in your browser and almost none that require no plugins.&lt;br /&gt;&lt;br /&gt;There's already a first Alpha version available here (but with just a single puzzle):&lt;br /&gt;&lt;a href="http://www.tapper-ware.net/sudoku/"&gt;Here!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The feature list is already longer than for most other Sudoku games:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Use the buttons at the bottom to add notes to the selected field.&lt;/li&gt;&lt;li&gt;Use the buttons at the right to confirm a number.&lt;/li&gt;&lt;li&gt;Use the "?" to get all notes automatically.&lt;/li&gt;&lt;li&gt;You can't confirm numbers that collie with other numbers in the field, however you can enter numbers that are simply wrong.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;So what's still missing (aside from a new UI):&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Automatic Solver&lt;/li&gt;&lt;li&gt;Generator&lt;/li&gt;&lt;li&gt;Tabs for different versions of the same puzzle&lt;/li&gt;&lt;li&gt;True handwritten notes&lt;/li&gt;&lt;li&gt;Menu to enable/disable solvers.&lt;/li&gt;&lt;/ul&gt;Did I forget anything? Tell me!&lt;br /&gt;&lt;br /&gt;Update:&lt;br /&gt;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 &lt;a href="http://ostermiller.org/qqwing/"&gt;QQwing&lt;/a&gt;, 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".</description><link>http://www.tapper-ware.net/2007/02/sudoku_05.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-4999875625813770812</guid><pubDate>Thu, 25 Jan 2007 18:16:00 +0000</pubDate><atom:updated>2007-01-25T19:17:47.083+01:00</atom:updated><title>Tutorial for native ARM PalmOS applications using PRC-Tools</title><description>&lt;p style="margin-bottom: 0cm;"&gt;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.&lt;/p&gt; &lt;p style="margin-bottom: 0cm;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0cm;"&gt;Basically, this document is divided into the following parts:&lt;/p&gt; &lt;ol&gt;&lt;li&gt;&lt;p style="margin-bottom: 0cm;"&gt;Tools Setup&lt;/p&gt;  &lt;ol&gt;&lt;li&gt;&lt;p style="margin-bottom: 0cm;"&gt;Cygwin&lt;/p&gt;   &lt;/li&gt;&lt;li&gt;&lt;p style="margin-bottom: 0cm;"&gt;PRC-Tools&lt;/p&gt;   &lt;/li&gt;&lt;li&gt;&lt;p style="margin-bottom: 0cm;"&gt;PalmOS SDK&lt;/p&gt;   &lt;/li&gt;&lt;li&gt;&lt;p style="margin-bottom: 0cm;"&gt;PEAL&lt;/p&gt;   &lt;/li&gt;&lt;li&gt;&lt;p style="margin-bottom: 0cm;"&gt;PARM Lib&lt;/p&gt;   &lt;/li&gt;&lt;li&gt;&lt;p style="margin-bottom: 0cm;"&gt;pilrc&lt;/p&gt;  &lt;/li&gt;&lt;/ol&gt; &lt;/li&gt;&lt;/ol&gt; &lt;p style="margin-bottom: 0cm;"&gt;&lt;br /&gt;&lt;/p&gt; &lt;p style="margin-bottom: 0cm;"&gt;The breakout game will be posted lateron :)&lt;/p&gt; &lt;h1 class="western"&gt;Tools&lt;/h1&gt; &lt;p&gt;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:&lt;/p&gt; &lt;h2 class="western"&gt;Cygwin (and PRC-Tools)&lt;/h2&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;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).&lt;/p&gt; &lt;p&gt;Installation is very simple, just download the installer from &lt;a href="http://www.cygwin.com/"&gt;http://www.cygwin.com/&lt;/a&gt; (“Install or update now! (using setup.exe)”) and run it. Chose the following options:&lt;/p&gt; &lt;p&gt;“Next” -&gt;&lt;/p&gt; &lt;p&gt;“Install from the Internet”, “Next” -&gt;&lt;/p&gt; &lt;p&gt;“Root Directory” (Enter the path where you want to install Cygwin), “Install for All Users”, “Default Text File Type Unix / binary”, “Next” -&gt;&lt;/p&gt; &lt;p&gt;“Local Package Directory” (Enter path where downloaded files should be saved, so you can reuse them when reinstalling Cygwin), “Next” -&gt;&lt;/p&gt; &lt;p&gt;“Direct Connection” or whatever you need to get a connection to the internet, “Next” -&gt;&lt;/p&gt; &lt;p&gt;Enter “&lt;a href="http://prc-tools.sourceforge.net/"&gt;http://prc-tools.sourceforge.net&lt;/a&gt;” into the “User URL:” field, press “Add”, Locate “&lt;a href="http://prc-tools.sourceforge.net/"&gt;http://prc-tools.sourceforge.net&lt;/a&gt;” in the list, click to select, locate a different mirror, for example “&lt;a href="http://ftp.heanet.ie/"&gt;http://ftp.heanet.ie&lt;/a&gt;” is pretty reliable, hold down “CTRL” while selecting it, check if both “&lt;a href="http://prc-tools.sourceforge.net/"&gt;http://prc-tools.sourceforge.net&lt;/a&gt;” and “&lt;a href="http://ftp.heanet.ie/"&gt;http://ftp.heanet.ie&lt;/a&gt;” are selected, “Next” -&gt;&lt;/p&gt; &lt;p&gt;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” -&gt;&lt;/p&gt; &lt;p&gt;“Installation Complete”&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;Now the compiler is installed and ready.&lt;/p&gt; &lt;h2 class="western"&gt;PalmOS SDK&lt;/h2&gt; &lt;p&gt;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 &lt;a href="http://www.developerpavilion.com/"&gt;http://www.developerpavilion.com/&lt;/a&gt;. 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)&lt;/p&gt; &lt;p&gt;Open the Cygwin Bash Shell from your Start Menu and perform the following actions:&lt;/p&gt; &lt;p&gt;cd /PalmDev/&lt;/p&gt; &lt;p&gt;tar -xzf palmos-sdk-5.0r3-1.tar.gz&lt;/p&gt; &lt;p&gt;palmdev-prep&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;(Of course, if the archive has a different file name, use that instead of “palmos-sdk-5.0r3-1.tar.gz”)&lt;/p&gt; &lt;p&gt;After running palmdev-prep you should get something like this:&lt;/p&gt; &lt;p style="margin-left: 2.5cm;"&gt;Checking SDKs in /PalmDev&lt;/p&gt; &lt;p style="margin-left: 2.5cm;"&gt;  sdk-5r3       headers in 'include', libraries in 'lib'&lt;/p&gt; &lt;p style="margin-left: 2.5cm;"&gt;When GCC is given no -palmos options, SDK '5r3' will be used by default&lt;/p&gt; &lt;p style="margin-left: 2.5cm;"&gt;Writing SDK details to configuration files...&lt;/p&gt; &lt;p style="margin-left: 2.5cm;"&gt;...done&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;h2 class="western"&gt;PEAL&lt;/h2&gt; &lt;p&gt;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 &lt;a href="http://www.sealiesoftware.com/peal/"&gt;http://www.sealiesoftware.com/peal/&lt;/a&gt; and place it in PalmDev as well. Extract it with&lt;/p&gt; &lt;p&gt;tar -xzf peal-2005_4_14.tar.gz&lt;/p&gt; &lt;p&gt;(Or whatever you named that file).&lt;/p&gt; &lt;p&gt;This will extract peal and create a directory named something like “peal-2005_4_14” to rename it to just “peal” enter&lt;/p&gt; &lt;p&gt;mv peal-2005_4_14 peal&lt;/p&gt; &lt;p&gt;Now, change to that directory with&lt;/p&gt; &lt;p&gt;cd peal&lt;/p&gt; &lt;p&gt;And go to the postlink directory&lt;/p&gt; &lt;p&gt;cd postlink&lt;/p&gt; &lt;p&gt;Now all you've got to do is compiling PEAL. Just type in&lt;/p&gt; &lt;p&gt;make&lt;/p&gt; &lt;p&gt;You'll get a few warnings, but after a few seconds you'll get back to the shell.&lt;/p&gt; &lt;p&gt;Enter&lt;/p&gt; &lt;p&gt;./peal-postlink&lt;/p&gt; &lt;p&gt;and you get the help message for PEAL.&lt;/p&gt; &lt;h2 class="western"&gt;PARM&lt;/h2&gt; &lt;p&gt;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 &lt;a href="http://www.tapper-ware.net/files/PARM.zip"&gt;http://www.tapper-ware.net/files/PARM.zip&lt;/a&gt; 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&lt;/p&gt; &lt;p&gt;cd /PalmDev/PARM/example/&lt;/p&gt; &lt;p&gt;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&lt;/p&gt; &lt;p&gt;./make68k.sh&lt;/p&gt; &lt;p&gt;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.&lt;/p&gt; &lt;p&gt;Now try to build the native application. Run&lt;/p&gt; &lt;p&gt;./makepno.sh&lt;/p&gt; &lt;p&gt;and it will first output a warning message&lt;/p&gt; &lt;p style="margin-left: 1.25cm;"&gt;In file included from ../../pnotest.c:27:&lt;/p&gt; &lt;p style="margin-left: 1.25cm;"&gt;../../pace_gen.c: In function `StrPrintF':&lt;/p&gt; &lt;p style="margin-left: 1.25cm;"&gt;../../pace_gen.c:133: warning: dereferencing type-punned pointer will break stri&lt;/p&gt; &lt;p style="margin-left: 1.25cm;"&gt;ct-aliasing rules&lt;/p&gt; &lt;p&gt;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 ( &lt;a href="http://scintilla.sourceforge.net/SciTEDownload.html"&gt;http://scintilla.sourceforge.net/SciTEDownload.html&lt;/a&gt; ), 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.&lt;/p&gt; &lt;h2 class="western"&gt;Pilrc&lt;/h2&gt; &lt;p&gt;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 &lt;a href="http://sourceforge.net/project/showfiles.php?group_id=7404"&gt;http://sourceforge.net/project/showfiles.php?group_id=7404&lt;/a&gt; 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.&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;See you then :)&lt;/p&gt; &lt;p&gt;Hans&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt; &lt;p&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;</description><link>http://www.tapper-ware.net/2007/01/tutorial-for-native-arm-palmos.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-2003540760830822854</guid><pubDate>Wed, 24 Jan 2007 21:01:00 +0000</pubDate><atom:updated>2007-01-24T22:43:35.366+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>tapwave</category><category domain='http://www.blogger.com/atom/ns#'>mobile</category><category domain='http://www.blogger.com/atom/ns#'>palmos</category><title>T8Launcher 0.4 with new layout engine and button input</title><description>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.&lt;br /&gt;The most notable improvement in this release is the ability to enter text with the buttons and joystick:&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;ul&gt;&lt;li&gt;New layout engine with skining&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Added wrappers for various HiRes APIs (not used yet)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Added partially complete 320x480 skin&lt;/li&gt;&lt;li&gt;Added button input&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;You can download it here:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Download:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a style="font-weight: bold;" href="http://www.tapper-ware.net/files/T8Launcher0.4.zip"&gt;Local&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;</description><link>http://www.tapper-ware.net/2007/01/t8launcher-04-with-new-layout-engine.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-1844774753828393455</guid><pubDate>Sat, 20 Jan 2007 17:43:00 +0000</pubDate><atom:updated>2007-01-20T18:50:57.729+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>tapwave</category><category domain='http://www.blogger.com/atom/ns#'>mobile</category><category domain='http://www.blogger.com/atom/ns#'>palmos</category><title>T8Launcher updated to 0.3</title><description>This is mainly a bugfixing release, but it also features a smaller footprint:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Fixed a problem where database-handles wouldn't get released, leading to a drawing problem with EDGE.&lt;/li&gt;&lt;li&gt;Fixed the problem with long application names "leaking" into the "abc1" button.&lt;/li&gt;&lt;li&gt;Optimized bitmaps for compression, bringing the filesize down to 213kb.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;You can download it here:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Download:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a style="font-weight: bold;" href="http://www.tapper-ware.net/files/T8Launcher0.3.zip"&gt;Local&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;</description><link>http://www.tapper-ware.net/2007/01/t8launcher-updated-to-03.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-5733584037236614530</guid><pubDate>Thu, 18 Jan 2007 22:53:00 +0000</pubDate><atom:updated>2007-01-24T22:44:03.653+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>tapwave</category><category domain='http://www.blogger.com/atom/ns#'>mobile</category><category domain='http://www.blogger.com/atom/ns#'>palmos</category><title>T8Launcher updated to 0.2</title><description>OK, it seems like the main problem was that the interface wasn't informative enough, so the changelog is pretty UI-centric:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Made text transparent, instead of white background&lt;/li&gt;&lt;li&gt;Added label "Launch" to launch button&lt;/li&gt;&lt;li&gt;Added label "Next App" to cycle apps button&lt;/li&gt;&lt;li&gt;Added label  "Backspace" to delete button&lt;/li&gt;&lt;li&gt;Added count of remaining matches to  cycle apps button (including label "Remaining Matches in List:")&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Added input string position to delete button (including label "Number of entered Chars:")&lt;/li&gt;&lt;li&gt;When there's no match for the current query string, display message and delete last character.&lt;/li&gt;&lt;li&gt;Fixed rotation after exiting from Portrait app&lt;/li&gt;&lt;li&gt;Don't display hidden apps anymore&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;You can download it here:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Download:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a style="font-weight: bold;" href="http://www.tapper-ware.net/files/T8Launcher0.2.zip"&gt;Local&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;</description><link>http://www.tapper-ware.net/2007/01/t8launcher-updated-to-02.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-631391131239245482</guid><pubDate>Tue, 16 Jan 2007 22:54:00 +0000</pubDate><atom:updated>2007-01-17T03:07:42.991+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>tapwave</category><category domain='http://www.blogger.com/atom/ns#'>mobile</category><category domain='http://www.blogger.com/atom/ns#'>palmos</category><title>T8Launcher for Tapwave Zodiac</title><description>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.tapper-ware.net/uploaded_images/screen-730959.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.tapper-ware.net/uploaded_images/screen-727399.png" alt="" border="0" /&gt;&lt;/a&gt;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.&lt;br /&gt;&lt;h3&gt;Download:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.tapper-ware.net/files/T8Launcher.zip"&gt;Local&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;FAQ:&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;How to install T8Launcher?&lt;/span&gt; Just Hotsync the PRC file contained in the ZIP file... that's all&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;How to exit T8Launcher?&lt;/span&gt; Enter "Home" to get back to the original Zodiac Launcher&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;How to disable T8Launcher?&lt;/span&gt; Unfortunately, that's not possible (yet). If you want to disable it, you have to uninstall it.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;How to uninstall T8Launcher?&lt;/span&gt; Just use a third-party utility like &lt;a href="http://www.nosleep.net/"&gt;Filez&lt;/a&gt; to delete the T8Launcher database.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;I see some strange programs like "MMConduit" amd "Error Reporter" in T8Launcher. What are these?&lt;/span&gt; These are hidden system utilities. So far T8Launcher ignores the "Hidden" file attribute of PalmOS. Just ignore these.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;A few programs with very long names leave display artefacts on the "ABC1" button. How can I get rid of these?&lt;/span&gt; You can't, this is a known issue... just ignore it for now.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;The program list looks pretty unsorted. Am I missing something?&lt;/span&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Even after entering the full name of the app another app gets listed first, for example Address XT after entering Address.&lt;/span&gt; Just use the "Down-Arrow" button to cycle all results. You'll get there eventually.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Is T8Launcher much slower than the original Zodiac Launcher?&lt;/span&gt; Actually, it's a hell of a lot faster, thanks to the native ARM code and simple structure.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;How can I launch an application from card?&lt;/span&gt; Unless you use a tool like PowerRun, you'll have to exit T8Launcher and use the standard launcher instead.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;How can I find out which code I have entered?&lt;/span&gt; You can't. But you can use the "Left-Arrow" button to fix spelling mistakes.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;How do I enter unlisted characters like space or asterisk?&lt;/span&gt; Don't. T8Launcher ignores anything but a-z, A-Z and 0-9. For example "my App**" would simply become "myapp".&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Can I create my own skin for T8Launcher?&lt;/span&gt; Well, yes and no. There are no special tools, but you can simply use a normal PRC editor to modify the resources.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Why is its name T8Launcher?&lt;/span&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;How will development continue?&lt;/span&gt; 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.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Why are a few buttons not centered vertically?&lt;/span&gt; I made a mistake when creating the images and I haven't gotten around to fixing it yet.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Which tools were used for this?&lt;/span&gt; &lt;a href="http://prc-tools.sourceforge.net/"&gt;PRC-Tools&lt;/a&gt;, &lt;a href="http://www.sealiesoftware.com/peal/"&gt;PEAL&lt;/a&gt; and &lt;a href="http://hansschmucker.googlepages.com/parm-palmarm"&gt;PARM&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;Feel free to use the comment section for suggestions and/or bug reports.</description><link>http://www.tapper-ware.net/2007/01/t8launcher-for-tapwave-zodiac.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-6094069202941040059</guid><pubDate>Mon, 01 Jan 2007 22:02:00 +0000</pubDate><atom:updated>2008-09-08T02:29:10.040+02:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>tapwave</category><category domain='http://www.blogger.com/atom/ns#'>mobile</category><category domain='http://www.blogger.com/atom/ns#'>games</category><category domain='http://www.blogger.com/atom/ns#'>palmos</category><category domain='http://www.blogger.com/atom/ns#'>abandonware</category><category domain='http://www.blogger.com/atom/ns#'>emulation</category><title>Another World for Tapwave Zodiac</title><description>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 &lt;a href="http://capers.free.fr/en/home.php?g=AnWd"&gt;Another World (a.k.a Out of this World) for the Zodiac&lt;/a&gt; by Chrilith.&lt;br /&gt;&lt;br /&gt;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).&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.tapper-ware.net/uploaded_images/AnotherWorld01-795929.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: right; cursor: pointer;" src="http://www.tapper-ware.net/uploaded_images/AnotherWorld01-792696.png" alt="" border="0" /&gt;&lt;/a&gt;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).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.tapper-ware.net/uploaded_images/AnotherWorld03-792981.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.tapper-ware.net/uploaded_images/AnotherWorld03-790847.png" alt="" border="0" /&gt;&lt;/a&gt;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:&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.tapper-ware.net/uploaded_images/AnotherWorld04-715482.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://www.tapper-ware.net/uploaded_images/AnotherWorld04-710112.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.tapper-ware.net/uploaded_images/AnotherWorld05-755963.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://www.tapper-ware.net/uploaded_images/AnotherWorld05-752816.png" alt="" border="0" /&gt;&lt;/a&gt;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.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.tapper-ware.net/uploaded_images/AnotherWorld12-792888.png"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://www.tapper-ware.net/uploaded_images/AnotherWorld12-789078.png" alt="" border="0" /&gt;&lt;/a&gt;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 &lt;a href="http://www.archive.org/"&gt;archive.org&lt;/a&gt;. 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).</description><link>http://www.tapper-ware.net/2007/01/another-world-for-tapwave-zodiac.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-2441649483703914371</guid><pubDate>Mon, 18 Dec 2006 11:22:00 +0000</pubDate><atom:updated>2006-12-18T15:16:17.713+01:00</atom:updated><title>Object Oriented Programming and Event Handlers</title><description>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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;html&gt;&lt;br /&gt; &amp;lt;head&gt;&lt;br /&gt;  &amp;lt;title&gt;HelloButton&amp;lt;/title&gt;&lt;br /&gt;  &amp;lt;script&gt;&amp;lt;/script&gt;&lt;br /&gt; &amp;lt;/head&gt;&lt;br /&gt; &amp;lt;body&gt;&lt;br /&gt; &amp;lt;/body&gt;&lt;br /&gt;&amp;lt;/html&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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:&lt;br /&gt;a) A constructor can't return anything, because it always returns the object it created.&lt;br /&gt;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").&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function button(title){&lt;br /&gt; /* Create an input element and save a reference in the element property */&lt;br /&gt; this.element=document.createElement("input");&lt;br /&gt; /* Set the type of the HTML element to "button" */&lt;br /&gt; this.element.setAttribute("type","button");&lt;br /&gt; /* Set the label of the HTML element to title */&lt;br /&gt; this.element.setAttribute("value", title);&lt;br /&gt; /* Append that element to the HTML body */&lt;br /&gt; document.getElementsByTagName("body")[0].appendChild(this.element);&lt;br /&gt; /* Set the title property to the supplied title */&lt;br /&gt; this.title=title;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;classname.prototype.methodname=function(parameters){code}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;button.prototype.showTitle=function(){&lt;br /&gt; alert(this.title);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;html&gt;&lt;br /&gt; &amp;lt;head&gt;&lt;br /&gt;  &amp;lt;title&gt;HelloButton&amp;lt;/title&gt;&lt;br /&gt;  &amp;lt;script&gt;&lt;br /&gt;function button(title){&lt;br /&gt; this.element=document.createElement("input");&lt;br /&gt; this.element.setAttribute("type","button");&lt;br /&gt; this.element.setAttribute("value", title);&lt;br /&gt; document.getElementsByTagName("body")[0].appendChild(this.element);&lt;br /&gt; this.title=title;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;button.prototype.showTitle=function(){&lt;br /&gt; alert(this.title);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function main(){&lt;br /&gt; var buttonObjects=new Array();&lt;br /&gt;  for(var i=0;i&amp;lt;3;i++){&lt;br /&gt;   buttonObjects[i]=new button("Button #"+i);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;  &amp;lt;/script&gt;&lt;br /&gt; &amp;lt;/head&gt;&lt;br /&gt; &amp;lt;body onload="main()"&gt;&lt;br /&gt; &amp;lt;/body&gt;&lt;br /&gt;&amp;lt;/html&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;The seemingly logical thing would be to just add a line that sets the onclick attribute to this.showTitle, right?&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;this.element.onclick=this.showTitle;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;this.element.onclick=this.showTitle.call(this);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;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.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;this.element.onclick=function(){this.showTitle.call(this)};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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":&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function methodize(methodize_func, methodize_scope){&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As we said before methodize should return a function:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function methodize(methodize_func,methodize_scope){&lt;br /&gt;    return (function(){});&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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".&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function methodize(methodize_func,methodize_scope){&lt;br /&gt;    return (function(){methodize_func.call(methodize_scope);});&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;this.element.onclick=methodize(this.showTitle,this);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;html&gt;&lt;br /&gt; &amp;lt;head&gt;&lt;br /&gt;  &amp;lt;title&gt;HelloButton&amp;lt;/title&gt;&lt;br /&gt;  &amp;lt;script&gt;&lt;br /&gt;function methodize(methodize_func,methodize_scope){&lt;br /&gt;    return (function(){methodize_func.call(methodize_scope);});&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function button(title){&lt;br /&gt; this.element=document.createElement("input");&lt;br /&gt; this.element.setAttribute("type","button");&lt;br /&gt; this.element.setAttribute("value", title);&lt;br /&gt; document.getElementsByTagName("body")[0].appendChild(this.element);&lt;br /&gt; this.title=title;&lt;br /&gt; this.element.onclick=methodize(this.showTitle,this);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;button.prototype.showTitle=function(){&lt;br /&gt; alert(this.title);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function main(){&lt;br /&gt; var buttonObjects=new Array();&lt;br /&gt;  for(var i=0;i&amp;lt;3;i++){&lt;br /&gt;   buttonObjects[i]=new button("Button #"+i);&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;  &amp;lt;/script&gt;&lt;br /&gt; &amp;lt;/head&gt;&lt;br /&gt; &amp;lt;body onload="main()"&gt;&lt;br /&gt; &amp;lt;/body&gt;&lt;br /&gt;&amp;lt;/html&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;P.S:&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;It's really not much of a deal&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function methodize(methodize_func,methodize_scope){&lt;br /&gt;    /* Copy the arguments array, which contains all parameters&lt;br /&gt;       to  methodize_args, except entries #0 and #1  (methodize_func&lt;br /&gt;       ,methodize_scope) */&lt;br /&gt;    var methodize_args=new Array();&lt;br /&gt;    for(var i=2;i&amp;lt;arguments.length;i++) methodize_args.push(arguments[i]);&lt;br /&gt;    /* Return a function that takes an event parameter itself&lt;br /&gt;       and passes it on to methodize_func, along with methodize_args */&lt;br /&gt;    return (function(evt){methodize_func.call(methodize_scope,evt,methodize_args);});&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;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.</description><link>http://www.tapper-ware.net/2006/12/object-oriented-programming-and-event.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-2514276884766965631</guid><pubDate>Fri, 08 Dec 2006 23:57:00 +0000</pubDate><atom:updated>2006-12-09T01:59:11.877+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>javascript</category><category domain='http://www.blogger.com/atom/ns#'>ajax</category><category domain='http://www.blogger.com/atom/ns#'>browsers</category><category domain='http://www.blogger.com/atom/ns#'>mozilla</category><title>A few words about Javascript</title><description>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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;What browser sniffing (a.k.a. useragant sniffing) does is "ask" the browser about itself and then taking appropriate measures. Seems simple, right?&lt;br /&gt;&lt;br /&gt;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 &lt;a href="http://www.zytrax.com/tech/web/browser_ids.htm"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new; font-weight: bold;"&gt;function wrapperAddEventListener(obj,type,callback){&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new; font-weight: bold;"&gt;   if(obj.addEventListener!=undefined) obj.addEventListener(type,callback,false);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new; font-weight: bold;"&gt;   else if(obj.attachEvent!=undefined) obj.attachEvent("on"+type,callback);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new; font-weight: bold;"&gt;   else alert("Sorry, your browser is not supported");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new; font-weight: bold;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And that's it. And it works for pretty much everything, except for some strange HTML behaviours. Now my minions: Spread the word.&lt;br /&gt;&lt;br /&gt;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 &lt;span style="font-style: italic;"&gt;that&lt;/span&gt;  difficult. See you next time.</description><link>http://www.tapper-ware.net/2006/12/few-words-about-javascript.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item><item><guid isPermaLink='false'>tag:blogger.com,1999:blog-9178810892351172948.post-5024970166592615274</guid><pubDate>Sat, 18 Nov 2006 18:34:00 +0000</pubDate><atom:updated>2006-11-19T17:08:08.371+01:00</atom:updated><category domain='http://www.blogger.com/atom/ns#'>patents</category><category domain='http://www.blogger.com/atom/ns#'>balmer</category><category domain='http://www.blogger.com/atom/ns#'>ajax</category><category domain='http://www.blogger.com/atom/ns#'>microsoft</category><title>Welcome everybody</title><description>I think it's high time I start yet another blog, after the last one has disappeared in the great free.fr cleanup.&lt;br /&gt;&lt;br /&gt;My name is Hans Schmucker and I'm a student at the &lt;a href="http://www.srh.de/cps/rde/xchg/SID-3F575FEA-0C6402CF/srh_dir/hs.xsl/336_ENG_HTML.html"&gt;University of Applied Sciences&lt;/a&gt;, 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 &lt;a href="http://gmodules.com/ig/ifr?url=http://hansschmucker.googlepages.com/patienceig.xml"&gt;Patience game&lt;/a&gt; alone has well over 6,000 users per day, so 10,000 is a safe bet).&lt;br /&gt;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 ( &lt;a href="http://www.redshift.hu/thequestpalm.htm"&gt;Quest&lt;/a&gt; for example uses some of my code for the PalmOS backend).&lt;br /&gt;&lt;br /&gt;So, now I want to offer you a quick look into the mind of a developer and PalmOS enthusiast :)&lt;br /&gt;&lt;br /&gt;What to start with? Ah, recent events: &lt;a href="http://en.wikipedia.org/wiki/Microsoft"&gt;Microsoft&lt;/a&gt;'s &lt;a href="http://en.wikipedia.org/wiki/Ballmer"&gt;Steve Ballmer&lt;/a&gt; threatening &lt;a href="http://en.wikipedia.org/wiki/Linux"&gt;Linux&lt;/a&gt; users, that they might get sued for violating Microsoft's patents.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;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.&lt;br /&gt;&lt;br /&gt;But let's get back to the topic at hand: Microsoft vs. Linux.&lt;br /&gt;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 &lt;a href="http://en.wikipedia.org/wiki/Fear%2C_uncertainty_and_doubt"&gt;FUD&lt;/a&gt; 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.&lt;br /&gt;&lt;br /&gt;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).&lt;br /&gt;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 &lt;a href="http://en.wikipedia.org/wiki/Graphical_Environment_Manager"&gt;GEM&lt;/a&gt; looks way to similar and it's a lot older.&lt;br /&gt;&lt;br /&gt;I think I'll stop here and let you think about it yourself. See you next time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Hans Schmucker&lt;/span&gt;</description><link>http://www.tapper-ware.net/2006/11/welcome-everybody.html</link><author>noreply@blogger.com (Hans Schmucker)</author></item></channel></rss>