<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-24283334</id><updated>2011-12-15T04:40:50.843+02:00</updated><category term='C#'/><category term='javascript'/><category term='sound'/><category term='python'/><category term='SSE'/><category term='tutorial'/><category term='Opera'/><category term='racing'/><category term='canvas'/><category term='physics'/><category term='Windows'/><category term='sample'/><category term='widgets'/><title type='text'>zomgistania</title><subtitle type='html'>Programming, C#, JavaScript, Widgets, etc.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default?start-index=101&amp;max-results=100'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>101</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-24283334.post-4616545688713742597</id><published>2008-11-29T14:38:00.003+02:00</published><updated>2008-11-29T14:40:35.759+02:00</updated><title type='text'>My currently active blog</title><content type='html'>Since this blog still has some traffic coming, I think I should update it a bit to let you all know that I'm currently blogging at &lt;a href="http://codeutopia.net/"&gt;CodeUtopia.net&lt;/a&gt;, so point your browsers that way!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-4616545688713742597?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/4616545688713742597/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=4616545688713742597' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/4616545688713742597'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/4616545688713742597'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2008/11/my-currently-active-blog.html' title='My currently active blog'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-4137639648830892277</id><published>2007-01-16T00:57:00.000+02:00</published><updated>2007-01-16T01:00:35.864+02:00</updated><title type='text'>I'm not dead!</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;&lt;br /&gt;&lt;br /&gt;Uh yeah, I'm not going to try explaining anything. I just was bored with blogging - so there hasn't really been any updates here&lt;br /&gt;&lt;br /&gt;Well, I did post a few to my blog at My Opera... and I will continue writing there until further notice.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://my.opera.com/zomg/blog/"&gt;Head over to my blog at the Opera Community&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-4137639648830892277?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/4137639648830892277/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=4137639648830892277' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/4137639648830892277'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/4137639648830892277'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2007/01/im-not-dead.html' title='I&apos;m not dead!'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-3530243681626550717</id><published>2006-10-30T02:13:00.000+02:00</published><updated>2006-10-30T02:22:46.023+02:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><category scheme='http://www.blogger.com/atom/ns#' term='racing'/><title type='text'>Racing games</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;I just uploaded &lt;a href="http://widgets.opera.com/widget/5681"&gt;my latest widget, called WidgetRacer&lt;/a&gt; to Opera Widgets.&lt;br /&gt;&lt;br /&gt;It's a top-down racing/sliding game and it has a track editor too!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've long been a fan of small top down racers like TurboSliders and Slicks'n'Slide and wanted to make my own sometime.&lt;br /&gt;&lt;br /&gt;Well, there it is!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It lets you save and load tracks to the widget, to the disk so you can share them with others. The track editor is quite good. Unlike most editors in games like this, you can create the shape of the road yourself so you're not limited to pre-selected pieces of road.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I was also planning on adding an online track database kind of thing, but sadly the MySQL server on my linux box went nuts... I could've done it with text files too I guess, but I ditched the idea for now.&lt;br /&gt;&lt;br /&gt;I'll implement it later for sure, though. It doesn't really require that much even with text files but some extra stuff to make sure the files don't get corrupted etc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Another cool thing would be two player game on the same computer or over network.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;2 players on the same computer is a possible option. I'm thinking about adding it in an update sometime, as it doesn't require much more than adding the keys... another thing is if the cars need to collide... that's gonna require some more work.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The thing is, however, that the game is made in JavaScript and uses the canvas element.... making it slow as heck on anything but a rather good PC... oh well, I'm considering remaking it in 3D in C# ;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Kind of tired at the moment, so I won't be going into more details as I'm having trouble thinking... hehe&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Oh yeah.&lt;br /&gt;&lt;br /&gt;100th post! w00t!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-3530243681626550717?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/3530243681626550717/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=3530243681626550717' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/3530243681626550717'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/3530243681626550717'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/10/racing-games.html' title='Racing games'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-2737503492450836533</id><published>2006-10-16T15:08:00.000+03:00</published><updated>2006-10-16T16:21:38.104+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='canvas'/><category scheme='http://www.blogger.com/atom/ns#' term='Opera'/><title type='text'>Canvas stuff</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;I've been lately experimenting a lot with the canvas element.&lt;br /&gt;&lt;br /&gt;For those of you who don't know what this "canvas" thing I'm talking about is, it's a new element in HTML, supported by Firefox and Opera at the moment. You can use it to draw graphics and such, like in games.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The first thing I made, was an Asteroids clone.&lt;br /&gt;Currently available in widget form from &lt;a href="http://widgets.opera.com/widget/5511"&gt;the opera widgets page&lt;/a&gt;, it's a pretty cool game, I might even say.&lt;br /&gt;&lt;br /&gt;It's actually rather simple to draw different shapes and such with canvas... you just define the starting point and then it's a game of "connect the dots": just give it the points you want to draw lines to. Pretty simple stuff.&lt;br /&gt;&lt;br /&gt;You can even do translations, rotations and scaling on the graphics, which might be expected from a vertex based renderer like DirectX. For example the asteroids are just defined as a few points, then stroked with a single command... they can be rotated as simply as calling a function and giving it the angle in radians.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The second experimental game is a Missile Command -style shooting game. &lt;a href="http://widgets.opera.com/widget/5545"&gt;Opera Command&lt;/a&gt;, as I call it, is also available from &lt;a href="http://widgets.opera.com/widget/5545"&gt;widgets.opera.com&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The non-widgetized version of it also worked on firefox... somewhat. Your own missiles wouldn't fire for some reason. Oh well, Firefox is so crappy anyway ;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There's only one issue with canvas, though: JavaScript.&lt;br /&gt;&lt;br /&gt;JavaScript is very slow compared to most programming languages which are usually used to make games. It seems that the canvas itself is okay rendering performance-wise, but the bottleneck is the scripting language.&lt;br /&gt;&lt;br /&gt;Do a lot of math, like precise collision detection (say... pool), and you'll bog down everything. Opera's JavaScript engine is the fastest I've seen yet, and it's still slowing down when there's much action on the screen.&lt;br /&gt;&lt;br /&gt;This leads to the fun part: optimization. Try to avoid every command.&lt;br /&gt;&lt;br /&gt;An issue caused by slowdown of JS on slower machines cause another issue: the games run faster on other computers than others... this could be avoided if one introduced proper timing into the script.&lt;br /&gt;&lt;br /&gt;That, however, would require even more calculations per frame... you'd need to take at least one new Date object per frame so you could calculate how long the last frame took... I haven't tried this yet, so I can't say for sure if it has a large impact, but considering that avoiding unnecessary things in JS is good...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The key in JS+canvas game dev: simplicity?&lt;br /&gt;&lt;br /&gt;Take the explosions in Opera Command for example. There's no image involved or complicated shapes... only an expanding circle which is filled with a gradient. And it still looks pretty good!&lt;br /&gt;&lt;br /&gt;I noticed a slight detoriation in the speed when I added the little missile graphics. I wonder if it would've been a better idea to just create them as lines instead of using a .png image...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It would seem that using images doesn't have much difference over using circles and paths and such if you look at the speed. For example in the Asteroids game, there were no images used in rendering and it still slows down a bit if there are lots of asteroids going around etc., Opera Command on the other hand has the little missile graphics and the city graphics being rendered.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So it seems to stand that the more going on -&amp;gt; the slower things will be. Well, this stands in every programming language, but the limit of what you can do comes very quickly in JavaScript, especially on slower machines.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-2737503492450836533?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/2737503492450836533/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=2737503492450836533' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/2737503492450836533'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/2737503492450836533'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/10/canvas-stuff.html' title='Canvas stuff'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115996718927114469</id><published>2006-10-04T15:47:00.000+03:00</published><updated>2006-10-04T16:06:30.126+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><title type='text'>Sounds are problematic, splitting images is not</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;In my latest widget, &lt;a href="http://widgets.opera.com/widget/5405"&gt;the Reaction Game&lt;/a&gt;, I wanted to have some sounds.&lt;br /&gt;&lt;br /&gt;The basic idea of the game is that some lights will turn on and you have to click on them... sometimes you may have to click on the same light more than once. This might be a bit confusing, as when you click on the light and it doesn't turn off you might think "wtf, why did it stay on?"&lt;br /&gt;&lt;br /&gt;This is why I wanted to add different beep sounds for each of the lights.&lt;br /&gt;&lt;br /&gt;There are few options to do it:&lt;br /&gt;- Use a .swf file which can play sounds (&lt;a href="http://my.opera.com/community/forums/topic.dml?id=146253&amp;t=1159965891&amp;page=1#comment1706847"&gt;See my post here&lt;/a&gt;)&lt;br /&gt;- Use the object tag&lt;br /&gt;- Use the embed tag&lt;br /&gt;- Use the Audio object in JavaScript&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The .swf file which can play sounds&lt;/b&gt;...&lt;br /&gt;This one &lt;i&gt;used&lt;/i&gt; to work. I don't know if it was Opera 9.01 or 9.02 which broke the functionality, though. It still works outside widgets, though.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The object tag&lt;/b&gt;...&lt;br /&gt;works outside widgets but inside widgets causes them to freeze.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The embed tag&lt;/b&gt;...&lt;br /&gt;does the same as the object tag&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Audio object&lt;/b&gt;...&lt;br /&gt;the same as the two above&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are so many alternatives, yet none works. Why? Get to fixin' it, Opera Software!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the other news, I've again released a bunch of new widgets.&lt;br /&gt;&lt;br /&gt;I'll describe one here because it has a pretty intresting approach to doing some things...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://widgets.opera.com/widget/5373"&gt;The Puzzle Creator&lt;/a&gt; widget lets you create a jigsaw puzzle of any picture on the internet. You just give it the URL of the image and stuff like how many columns and rows of pieces you want.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As you might know, JavaScript doesn't really have any image manipulation functions, so you can't just take an image and split it in smaller pieces. The trick employed here is the CSS clip property!&lt;br /&gt;&lt;br /&gt;You can use the clip property in CSS to define the area of an element you want to display... so, to get small pieces of an image we just calculate the size and position of the part we want to show and use the clip property. Pretty neat, even if I say so myself.&lt;br /&gt;&lt;br /&gt;This, however has a small problem again... if you clip an image, the image's width and height will still be the same and the parts outside the clip area won't show but they are there, so the area inside the clip rectangle will be offset from the corner.&lt;br /&gt;&lt;br /&gt;To fix this, the widget just calculates the offset and saves it to each piece with setAttribute. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For those of you who aren't using Opera (why?!), &lt;a href="http://iikeli.ath.cx:3000/projects/puzzle/index.html"&gt;here's a non-widget version of the puzzle creator&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There might be one additional approach to doing this with JS. Both Firefox and Opera have an element called "canvas". This can be used to draw graphics, a bit like GDI for example. &lt;br /&gt;&lt;br /&gt;As I don't have much experience in using the canvas, I can't say this for sure, but you could just put the image on the canvas and draw white on top of parts you want to hide. I'm pretty sure you can use images on the canvas like that, so it should be quite possible.&lt;br /&gt;&lt;br /&gt;With this approach, however, you would have to code in various things like click events and such. When using separate html elements, changing the places of the pieces is as simple as changing different left and top attributes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That's all for now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115996718927114469?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115996718927114469/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115996718927114469' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115996718927114469'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115996718927114469'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/10/sounds-are-problematic-splitting.html' title='Sounds are problematic, splitting images is not'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115969365146660694</id><published>2006-10-01T11:53:00.000+03:00</published><updated>2006-10-01T12:07:31.513+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><title type='text'>&lt;select&gt; boxes</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;I'm sitting in the #Javascript channel in Quakenet at IRC. Pretty often you see someone who wants to something to happen when you choose an item from a select box...&lt;br /&gt;&lt;br /&gt;"I want to show some fields if user selects X from my list"&lt;br /&gt;&lt;br /&gt;"I want to have 3 &amp;lt;select&amp;gt; boxes and when you choose 1 there will come a new select box.. how can I do that?"&lt;br /&gt;&lt;br /&gt;etc.&lt;br /&gt;&lt;br /&gt;I made a quite simple &lt;a href="http://admins.fi/~eagleeye/forms.html"&gt;sample script&lt;/a&gt; of this.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I thought it might be a good idea to explain it a bit, though.&lt;br /&gt;&lt;br /&gt;Starting with the HTML code:&lt;br /&gt;&lt;br /&gt;the basic idea is to have a select element and give it an ID so we can easily use it in JavaScript. In the example, the select elements ID is "selector".&lt;br /&gt;&lt;br /&gt;Then we need something to show and hide depending on what's selected: in the example, a couple of div elements. Yet again, we should give these some IDs so they can be easily accessed from JS... in the example they're called "right_1" and "right_2".&lt;br /&gt;&lt;br /&gt;These divs are also hidden by default using the CSS definition "display: none".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In the select element, we use the onchange event to call our JavaScript function. As you can see from the HTML code, onChange="ShowRight()"&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now let's look at the JavaScript function...&lt;br /&gt;&lt;br /&gt;First, we use document.getElementById() function to find the select element. We use .selectedIndex to find the numeric index of the item which is currently selected... note that the first one is 0, not 1.&lt;br /&gt;&lt;br /&gt;We save this index to a variable called "selected".&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After this we hide the two divs we have. This is because the user might have selected something from the select already and one of the divs might be visible.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then we have a switch statement. This is used to do something depending on what the value saved in selected is.&lt;br /&gt;&lt;br /&gt;As you can see, if the value is 1 the code uses document.getElementById() to find right_1 and then sets it's CSS value display to "block" and if the value is 2, it shows the right_2 element instead.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Pretty simple stuff, isn't it?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115969365146660694?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115969365146660694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115969365146660694' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115969365146660694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115969365146660694'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/10/boxes.html' title='&amp;lt;select&amp;gt; boxes'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115933325558797843</id><published>2006-09-27T08:00:00.000+03:00</published><updated>2006-09-27T08:00:55.590+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><title type='text'>Widget stuff</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;Recently I posted &lt;a href="http://my.opera.com/community/forums/topic.dml?id=159442"&gt;how to save data from widgets to a file&lt;/a&gt; to the Opera forums... thought maybe I should put a link here too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are three new widgets I've been working on: &lt;a href="http://widgets.opera.com/widget/5223"&gt;Jack Bauer facts&lt;/a&gt;, &lt;a href="http://widgets.opera.com/widget/5169"&gt;IRC Listener&lt;/a&gt; and &lt;a href="http://widgets.opera.com/widget/5280"&gt;Online Player Search&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Jack Bauer facts is pretty basic stuff code-wise... it loads an XML file using XMLHttpRequest, which contains "facts" about Jack Bauer. Then it starts displaying facts about him. It's pretty funny, and I was going to make a Chuck Norris facts widget but someone beat me to it! :]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;IRC Listener is a bit more special piece. I might've mentioned it in the posts about Server-Sent Events. I used the Python SSE framework I made to create an SSE backend which sends the client my IRC logs from some channels. The IRC Listener widget uses this backend and lets the user watch the chat in the channels. It also let's the user pick which channel he/she wants to listen to. I won an Opera 9 t-shirt + some swag for this duo.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The third one, Online Player Search, was also a t-shirt competition inspired one. Using the service at gametiger.net, it lets you to search for players in online games. It's pretty neat, say your friend plays a lot of Counter-Strike under name "Pete", you can just type in "Pete", choose "Counter-Strike" and hit search. The widget then displays you a list of all Petes playing CS it found and the server IPs.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm also working on a game which uses SSE and JS. I'll leave it in the dust for now as I've had several problems (related to bugs in the browser) so I don't know if I'm going to get it done to even so much that I can mention it here :]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115933325558797843?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115933325558797843/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115933325558797843' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115933325558797843'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115933325558797843'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/09/widget-stuff_27.html' title='Widget stuff'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115915659366289381</id><published>2006-09-25T06:34:00.000+03:00</published><updated>2006-09-25T06:56:34.150+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Recipe for success: Lack of sleep</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;I always get my best ideas when I'm tired! Same happened again just an hour or so back...&lt;br /&gt;&lt;br /&gt;I thought.. could I make the floppy drive crucnch? Like if it was trying to read a floppy.&lt;br /&gt;&lt;br /&gt;This idea sprung from the fun I had had with the beeper program: I ran it on a computer at school and the few guys there thought the computer was gonna blow up and backed away from it... it was a pretty fun sight ;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So I thought that making the floppy drive crunch would be a nice effect for fooling with people...&lt;br /&gt;&lt;br /&gt;Let's see: if I try to read all files from the disk, will that cause a noise even if there's no disk in the drive? Yes!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So let's put that on an endless loop.... *DURRRRRRRRRRRRRRRRRRRRRRRRRR*&lt;br /&gt;&lt;br /&gt;Got my floppy noise... but hey, maybe I could make the CD tray open and close? That's simple. Just some mci stuff.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So now I have a crazy beep, a scary floppy drive noise and a cd tray which opens and closes on its own. What more?&lt;br /&gt;&lt;br /&gt;How about the harddisk making a noise? Sure, why not... &lt;br /&gt;&lt;br /&gt;This one was a bit more complicated as it seemed just getting all files from C wouldn't make a good noise for long so I thought I'd just loop through all drives, all folders and so on again and again, but to do that I needed a list of all hard disks.&lt;br /&gt;&lt;br /&gt;After getting the list, making the file looping was simple.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Okay so I had together the ultimate "scare your computer illiterate friend" program... but I wanted to add more!&lt;br /&gt;&lt;br /&gt;I know, let's make it so that every window disappears and reappears and that loops again and again! I called this the -madness parameter. It is pretty intense actually.&lt;br /&gt;&lt;br /&gt;Madness is so mad, that it's even quite difficult to stop it! Press ctrl-alt-del and go to task manager... no! The task manager starts blinking!.. you gotta be pretty fast to stop the madness ;)&lt;br /&gt;&lt;br /&gt;I tried using &lt;a href="http://zeeohemgee.blogspot.com/2006/04/creating-global-keyboard-hook-in-c.html"&gt;my old global keyboard hook code&lt;/a&gt; to create a stop command for it. The global keyboard hook would read even if the application itself wasn't visible, so it should've done the job... but it appears it didn't work in a console application and I was too lazy to make it a windows forms app. Oh well... :]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;To experience the madness or scare your friends, &lt;a href="http://admins.fi/~eagleeye/projects/funnay.exe"&gt;download the exe&lt;/a&gt;. Parameters for the exe are -disk, -beep, -cd, -drives, -madness and -all.&lt;br /&gt;&lt;br /&gt;-disk makes the floppy crunch, -beep beeps like a crazy, -cd opens and closes the cd tray, -drives crunches the HDD, -madness makes windows flip out and -all does everything EXCEPT -madness.. so to get everything, you need to type funnay.exe -all -madness&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;NOTE: If -disk breaks your floppy drive or a floppy disk inside the drive, I'm not responsible. I don't know if the drive can take the constant polling for very long periods of time.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115915659366289381?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115915659366289381/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115915659366289381' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115915659366289381'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115915659366289381'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/09/recipe-for-success-lack-of-sleep.html' title='Recipe for success: Lack of sleep'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115900111972805737</id><published>2006-09-23T11:31:00.000+03:00</published><updated>2006-09-23T11:49:38.296+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><title type='text'>Bettering the input boxes</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;I was playing around with JS again and was looking at &lt;a href="http://zeeohemgee.blogspot.com/2006/08/opera-widgets-imitating-alert-behavior.html"&gt;my old messagebox code&lt;/a&gt;... which I deemed crap.&lt;br /&gt;&lt;br /&gt;So I just took it from the start and made a completely new class for showing boxes which can be used for asking for user input or just displaying info like alert() and such.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function GenericBox(cssclass, titletxt, messagetxt, showInput, showButton, validatorFunc)&lt;br /&gt;{&lt;br /&gt; //this function is called when the user presses the OK button&lt;br /&gt; var validator = validatorFunc;&lt;br /&gt;&lt;br /&gt; //Save a reference to this object for later&lt;br /&gt; var self = this;&lt;br /&gt; &lt;br /&gt; //create the div for the messagebox&lt;br /&gt; //the box is just defined in CSS and the CSS class it uses&lt;br /&gt; //is defined in the parameter cssclass&lt;br /&gt; var element = document.createElement('div');&lt;br /&gt; element.className = cssclass;&lt;br /&gt; &lt;br /&gt;&lt;br /&gt; //create the title&lt;br /&gt; var title = document.createElement('h1');&lt;br /&gt; title.innerHTML = titletxt;&lt;br /&gt; element.appendChild(title);&lt;br /&gt; &lt;br /&gt; //create the message&lt;br /&gt; var message = document.createElement('p');&lt;br /&gt; message.innerHTML = messagetxt;&lt;br /&gt; element.appendChild(message);&lt;br /&gt; &lt;br /&gt; //create the input box&lt;br /&gt; var input = document.createElement('input');&lt;br /&gt; input.type = 'text';&lt;br /&gt; input.onkeydown = function()&lt;br /&gt; {&lt;br /&gt;  if(!e) var e = window.event;&lt;br /&gt; &lt;br /&gt;  //if the user presses enter when in the input,&lt;br /&gt;  //call the validator function with a reference to&lt;br /&gt;  //this object and the value of the input field&lt;br /&gt;  if(e.keyCode == 13)&lt;br /&gt;   validator(self,this.value);    &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; //hide input if user doesn't want to show it&lt;br /&gt; if(!showInput)&lt;br /&gt;  input.style.display = 'none';&lt;br /&gt; &lt;br /&gt; element.appendChild(input);&lt;br /&gt; &lt;br /&gt; element.appendChild(document.createElement('br'));&lt;br /&gt; &lt;br /&gt; //Create the OK button&lt;br /&gt; var button = document.createElement('input');&lt;br /&gt; button.type = 'button';&lt;br /&gt; button.value = 'OK';&lt;br /&gt; button.onclick = function()&lt;br /&gt; {&lt;br /&gt;  //when the user clicks this we send the data to the func&lt;br /&gt;  validator(self,this.previousSibling.previousSibling.value);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; //again, hide if not wanted&lt;br /&gt; if(!showButton)&lt;br /&gt;  button.style.display = 'none';&lt;br /&gt; &lt;br /&gt; element.appendChild(button);&lt;br /&gt; &lt;br /&gt; var visible = false;&lt;br /&gt; &lt;br /&gt; //used for showing the box&lt;br /&gt; this.Show = function()&lt;br /&gt; {&lt;br /&gt;  if(!visible)&lt;br /&gt;  {&lt;br /&gt;   document.appendChild(element);&lt;br /&gt;   visible = true;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; //used for hiding the box&lt;br /&gt; this.Hide = function()&lt;br /&gt; {&lt;br /&gt;  if(visible)&lt;br /&gt;  {&lt;br /&gt;   document.removeChild(element)&lt;br /&gt;   visible = false; &lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; //use this to change the message&lt;br /&gt; this.SetText = function(newtext)&lt;br /&gt; {&lt;br /&gt;  message.innerHTML = newtext; &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; //this can hide the inputs in the box&lt;br /&gt; this.HideInputs = function()&lt;br /&gt; {&lt;br /&gt;  input.style.display = 'none';&lt;br /&gt;  button.style.display = 'none';&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The basic use is pretty simple again...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function ShowBox()&lt;br /&gt;{&lt;br /&gt; var box = new GenericBox('genericbox','Example','This is an example box',false,true,HideMe);&lt;br /&gt; box.Show();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function HideMe(obj,input)&lt;br /&gt;{&lt;br /&gt; obj.Hide();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;When calling ShowBox, the user would get a box with title "Example" and text "This is an example box" which has a button OK. When the OK button is pressed, HideMe function gets called. The HideMe function just uses the reference to the object and hides it with the Hide() function. &lt;br /&gt;&lt;br /&gt;Pretty simple huh?&lt;br /&gt;&lt;br /&gt;the CSS class for the box should at least contain the details on the box like position: absolute and it's left and top position and width and height and such.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If the above code would've set the showInput to true, the input parameter in the HideMe function would contain the data in the input field.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The SetText and HideInputs functions are there so you can re-use the box a bit... say, you're sending the data from the input box to a web page so you could do something like first use HideInputs to hide the inputs and then SetText and change the message to something like "Working..." so the user knows you're processing the data.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115900111972805737?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115900111972805737/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115900111972805737' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115900111972805737'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115900111972805737'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/09/bettering-input-boxes.html' title='Bettering the input boxes'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115819939212447676</id><published>2006-09-14T04:15:00.000+03:00</published><updated>2006-09-14T05:03:12.230+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sound'/><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Beep beep.</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;Being somewhat bored and such again, I figured out a way to use the PC Speaker to play sounds with C#. It's actually pretty simple, just use the winapi Beep() function.&lt;br /&gt;&lt;br /&gt;Of course that's not all! I made a small class which can be used to play songs (or annoying beeps) with the PC speaker and a console app which uses it.&lt;br /&gt;&lt;br /&gt;The notation is simple enough: &lt;frequency&gt;,&lt;time&gt;&lt;br /&gt;Frequency is a number between 37 and 32 767 (the highest frequencies might not play on all PC speakers) and time is the time the beep should play in milliseconds. So for example to play a few beeps for half a second you could write..&lt;br /&gt;&lt;br /&gt;2500,500 1200,500 400,500&lt;br /&gt;&lt;br /&gt;You can also define a range of frequencies...&lt;br /&gt;&lt;br /&gt;2500-3000,1&lt;br /&gt;&lt;br /&gt;The above would play 2500,2501,2502... and so on up to 3000, each frequency for 1 ms.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The cool thing is that, being a console application, you can use the piping operator &amp;lt; to direct a file to the input of the app!&lt;br /&gt;&lt;br /&gt;That way you could write your magnificent song into a file and just use beepage.exe &amp;lt; mysong.txt to play it. Neat huh? =)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Download&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;You can &lt;a href="http://admins.fi/~eagleeye/projects/beep/beepage.exe"&gt;download the exe&lt;/a&gt; or &lt;a href="http://admins.fi/~eagleeye/beep/beepage.zip"&gt;source-code for the project&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Try installing this to someone elses computer and use the windows timed tasks feature to have it make some intresting noises a while later when he/she is back for a good laugh. If you use the beepage.exe -all parameter, it will play every frequency which causes a pretty freaky sound... ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115819939212447676?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115819939212447676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115819939212447676' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115819939212447676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115819939212447676'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/09/beep-beep.html' title='Beep beep.'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115790400955593464</id><published>2006-09-10T18:46:00.000+03:00</published><updated>2006-09-10T19:00:09.586+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='physics'/><title type='text'>Gravity and collisions</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;I was kind of bored yesterday, so I made &lt;a href="http://zomg.thegroup.fi/boing.html" target="_blank"&gt;this&lt;/a&gt; with JavaScript.&lt;br /&gt;&lt;br /&gt;Doesn't require much code to get a realistic-ish looking bouncing done.&lt;br /&gt;It has a few flaws though... the ball goes like one of those superballs when it goes up or down which isn't necessarily a bad thing but for anything else than a superball simulation...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115790400955593464?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115790400955593464/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115790400955593464' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115790400955593464'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115790400955593464'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/09/gravity-and-collisions.html' title='Gravity and collisions'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115775394564066028</id><published>2006-09-09T00:48:00.001+03:00</published><updated>2006-09-09T01:23:41.946+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSE'/><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><title type='text'>Writing SSE backends with Python</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;And here we go again with the snake...&lt;br /&gt;&lt;br /&gt;As I mentioned in the &lt;a href="http://zeeohemgee.blogspot.com/2006/09/server-sent-events-new-chapter-in-ajax.html"&gt;last post&lt;/a&gt;, I wrote this server script for SSE in Python.&lt;br /&gt;&lt;br /&gt;Well, I thought it would be more worthwhile to turn it into a framework kind of thing, on which you can easily build your SSE backends.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Warning: the code and stuff are in Python and I'm not going to go into details about the language here. I'll just describe the functions and classes in the framework.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The basic implementation is built on the &lt;a href="http://twistedmatrix.com/trac/" target="_blank"&gt;Twisted networking framework&lt;/a&gt; for Python. If you want to know more about Twisted, you can find their docs from their page.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My framework consists of three classes: the SSEClient, SSEServer and Service classes.&lt;br /&gt;&lt;br /&gt;The SSEServer class is the "main" processor. It handles reading the console for input, pinging users and sending requests to the correct Services.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Service class is what the programmer will be mainly using.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The SSEClient is used as the client for the services. It contains the SSE request and methods to write data to the stream and such.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can &lt;a href="http://admins.fi/~eagleeye/python/sseframework.py"&gt;download the framework from here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;An example Service made with the framework can be &lt;a href="http://admins.fi/~eagleeye/python/sseexample.py"&gt;downloaded from here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The example service can be run with Python with python sseexample.py. It starts the server in port 3080.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Descriptions of the classes&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SSEServer:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;example = SSEServer(services,True,True)&lt;br /&gt;&lt;br /&gt;the SSEServer takes three parameters:&lt;br /&gt;a dict of the services&lt;br /&gt;True/False if you want it to ping users automatically&lt;br /&gt;True/False if you want it to read console input&lt;br /&gt;&lt;br /&gt;the format for the service dict:&lt;br /&gt;{'/service/path': ServiceClass(), '/second/service': SecondClass()}&lt;br /&gt;&lt;br /&gt;For example, if you set the path to '/', the service is accessible with http://yourserver:port/ and if you set it to '/example', it's accessible with http://yourserver:port/example.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Service:&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;example = Service('Service name')&lt;br /&gt;&lt;br /&gt;Service takes one parameter: the name of the service. The service itself does nothing, so you will have to make your own class which inherits from it.&lt;br /&gt;&lt;br /&gt;Service functions:&lt;br /&gt;&lt;br /&gt;parse(request) - this is called when a client wants to access the service. Override in your own class&lt;br /&gt;&lt;br /&gt;findClient(request) - can be used to see if the user has already opened an SSE session. Returns the SSEClient if found, otherwise None.&lt;br /&gt;&lt;br /&gt;startSession(client) - used to start a new SSE session. Pass an SSEClient as the parameter. After the session is created, it sends the clients session-id. Format:&lt;br /&gt;Event: session-id&lt;br /&gt;data: &lt;session_id&gt;&lt;br /&gt;&lt;br /&gt;broadcast(type,message) - sends a message to all clients. type is the event type and message is the data for the event&lt;br /&gt;&lt;br /&gt;ping() - sends a ping to every user who hasn't received a message in the last 60 seconds. Used automatically by the SSEServer pinger.&lt;br /&gt;&lt;br /&gt;drop(client) - removes a client from the list. Parameter is an SSEClient&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;SSEClient&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;example = SSEClient(service,request)&lt;br /&gt;&lt;br /&gt;Parameters for the SSEClient are the "owner" service and the client's request.&lt;br /&gt;&lt;br /&gt;You can override the SSEClient so you can add more variables to it, like the users name in a chat or something like that.&lt;br /&gt;&lt;br /&gt;functions:&lt;br /&gt;&lt;br /&gt;stop(reason) - automatically called when the users connection is closed. Calls the parent services drop method.&lt;br /&gt;&lt;br /&gt;sendMsg(type,data) - send a message to the client. type is the event type and data the event data. The data can also be a list and it will be handled properly.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There we go. Feel free to ask if you have anything on your mind.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115775394564066028?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115775394564066028/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115775394564066028' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115775394564066028'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115775394564066028'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/09/writing-sse-backends-with-python_09.html' title='Writing SSE backends with Python'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115752899039813021</id><published>2006-09-06T10:38:00.000+03:00</published><updated>2006-09-06T10:49:50.726+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SSE'/><category scheme='http://www.blogger.com/atom/ns#' term='python'/><category scheme='http://www.blogger.com/atom/ns#' term='Opera'/><title type='text'>Server Sent Events: The new chapter in AJAX</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;Opera 9 features some of the Server-Sent Events features from &lt;a href="http://whatwg.org/" target="_blank"&gt;WHATWG&lt;/a&gt; Web Applications 1.0 spec.&lt;br /&gt;&lt;br /&gt;But what on earth is that? Well, basically it means that your web page listens to messages from the server! You don't need to do XmlHttpRequests to the server to ask for more data, the server just sends the data to you instead.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;A good example of this technology is the &lt;a href="http://oxzone.opera.com/webchat/" target="_blank"&gt;Opera Web Chat&lt;/a&gt;. Note that it only works in Opera at the moment, as no other browser yet supports SSE.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I created a IRC log forwarder server using Python and Twisted. I first tried using PHP, but I found that it was much easier to have a dedicated server application running and serving clients than trying to keep track of them with PHP, which also seemed to have trouble keeping track of whether the user was disconnected from the page or not. Could've been a problem in my PHP configuration as well, but so what if I can do it easily with Python.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you are using Opera, you can find the log forwarder from http://iikeli.ath.cx:3080/&lt;br /&gt;&lt;br /&gt;to choose a channel use the channel get parameter, ie.&lt;br /&gt;http://iikeli.ath.cx:3080/?channel=lounge for #lounge and&lt;br /&gt;http://iikeli.ath.cx:3080/?channel=opera for #opera&lt;br /&gt;&lt;br /&gt;If no channel is selected, it defaults to #opera.&lt;br /&gt;&lt;br /&gt;At the moment there are only #opera and #lounge from irc.opera.com available, but I might add more if someone asks me to.&lt;br /&gt;&lt;br /&gt;Example HTML page which uses this can be found at http://iikeli.ath.cx:3000/projects/sse/irclog.php&lt;br /&gt;The channel get parameter works with that as well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I will post the source code for the server script later so hopefully others can learn from it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For more details on the implementation of SSE in Opera and sample code, visit the &lt;a href="http://my.opera.com/WebApplications/blog/show.dml/438711?cid=2063363" target="_blank"&gt;Opera Web Applications blog&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115752899039813021?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115752899039813021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115752899039813021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115752899039813021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115752899039813021'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/09/server-sent-events-new-chapter-in-ajax.html' title='Server Sent Events: The new chapter in AJAX'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115738473396307388</id><published>2006-09-04T18:41:00.000+03:00</published><updated>2006-09-04T18:47:55.213+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Taskbar Arranger</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;Here's something I made recently... a taskbar arranger tool.&lt;br /&gt;&lt;br /&gt;It's pretty useful if you have lots of programs running, as you can sort the taskbar in such order that the important programs are leftmost or such.&lt;br /&gt;&lt;br /&gt;You can &lt;a href="http://admins.fi/~eagleeye/Arranger.exe"&gt;download the .exe from here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've also uploaded the source-code for the app, which is &lt;a href="http://admins.fi/~eagleeye/arranger.zip"&gt;downloadable from here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Written in C# as usual and it uses some Windows API functions which aren't available in native C# with P/Invoke.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115738473396307388?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115738473396307388/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115738473396307388' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115738473396307388'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115738473396307388'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/09/taskbar-arranger_04.html' title='Taskbar Arranger'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115649559692948039</id><published>2006-08-25T10:26:00.000+03:00</published><updated>2006-08-25T11:46:37.150+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><title type='text'>Form validation with JS</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;How often do you fill in a form and submit it only to get a page telling you that something was wrong in your input? Yeah, pretty often...&lt;br /&gt;&lt;br /&gt;Even though it's very easy to add simple JavaScript validation to the form which tells the user if his input is wrong, almost no form ever has such features. &lt;br /&gt;&lt;br /&gt;In this post, I'll introduce some simple means to check the values in forms using JavaScript to provide a better browsing experience to the user.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How does this work?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In the HTML Input element you can have an onChange event and an onKeyUp event (and some others). We can use these to run JavaScript code.&lt;br /&gt;&lt;br /&gt;We run a check and if the value in the field isn't what it should be, we can, for example, highlight the field with a red background color or display a message to the user telling the input is wrong.&lt;br /&gt;&lt;br /&gt;Of course this will only work if the user has JavaScript enabled. Most browsers these days have JS support and users usually leave it on, but do not forget to validate the form inputs server-side using your scripting language of choice.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Using the events&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The two important events are onChange and onKeyUp. &lt;br /&gt;&lt;br /&gt;The onChange event fires when the value in an input field changes and the user selects something else, ie. clicks on somewhere else on the page or presses tab.&lt;br /&gt;&lt;br /&gt;The onKeyUp event fires every time the user releases a key, ie. when typing.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's an example of using onChange&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;input type="text" onChange="if(isNaN(this.value)) { alert('The value is not a number'); }" /&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The code checks if the value in the field is Not a Number (NaN). If the input is something else than a number, the user gets a message saying "The value is not a number".&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note: the this keyword used in the check refers to the input element itself, so we can use it to get the value of the field&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Validating&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To make validating the fields easier, let's first create some functions.&lt;br /&gt;&lt;br /&gt;Often there are fields that require numeric input, so let's create a function which can be used to check if the value is a number and optionally if it's between some values.&lt;br /&gt;&lt;br /&gt;Another task is to limit the maximum input in a field so the user can only write, say, up to 250 characters to a field, so we'll create a function for that too.&lt;br /&gt;&lt;br /&gt;Finally we'll also use a regular expression to see if the value in a field is a valid email address.&lt;br /&gt;&lt;br /&gt;You can download a script file with all the functions &lt;a href="http://admins.fi/~eagleeye/articles/forms.js"&gt;from here&lt;/a&gt;, but I suggest you still go through the explanations if you're not completely familiar with them.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Let's start with the number check...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function IsNumber(field,start,end)&lt;br /&gt;{&lt;br /&gt; //Check if value is not a number&lt;br /&gt; if(isNaN(field.value))&lt;br /&gt;  return false;&lt;br /&gt; &lt;br /&gt; //if start and end are defined&lt;br /&gt; //check if the number is between them&lt;br /&gt; if(start &amp;&amp; end)&lt;br /&gt; {  &lt;br /&gt;  if(field.value &gt;= start &amp;&amp; field.value &lt;= end)&lt;br /&gt;   return true;&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt;  return true;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This function should be pretty simple to understand. The field should be the input element and start and end are the numbers between which the value has to be, but they are optional.&lt;br /&gt;&lt;br /&gt;First, we just check if the value in the field is a number at all. If it isn't, we return false. After this we check if start and end are defined and if they are, compare the value to them.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next, the max size function..&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function MaxSize(field,num)&lt;br /&gt;{&lt;br /&gt; //if length of data is &gt; than max,&lt;br /&gt; //make it shorter&lt;br /&gt; if(field.value.length &gt; num)&lt;br /&gt;  field.value = field.value.substr(0,num); &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Yet again, the field should be the input element and num the maximum amount of characters allowed. The length of the value in the field is just compared against the num, and the substr method is used to make its length to num characters if it's too long.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And finally the email check..&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function IsEmail(field)&lt;br /&gt;{&lt;br /&gt; //this is a regular expression&lt;br /&gt; var expr = /^([a-zA-Z0-9_\.\-])+\@(([a-zA-Z0-9\-])+\.)+([a-zA-Z0-9]{2,4})+$/;&lt;br /&gt; &lt;br /&gt; //Check if regexp matches the value in the field&lt;br /&gt; if(expr.test(field.value))&lt;br /&gt;  return true;&lt;br /&gt;  &lt;br /&gt; return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;You don't need to understand the syntax of the regular expression, just know that it matches only valid email addresses, so we can use it to test whether or not the value is a valid email address.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;With these functions you can easily validate values in forms, but let's define one more function. This one can be used to highlight a field in some color&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function Highlight(obj,col)&lt;br /&gt;{&lt;br /&gt; //just set the bgcolor of obj to col&lt;br /&gt; obj.style.backgroundColor = col; &lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Yeah, we could probably just write obj.style.backgroundColor = 'something' when we want to change the color, but that's so much simpler to use and that's why we define it as a function.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Using our validation functions&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Look at this &lt;a href="http://admins.fi/~eagleeye/articles/forms.html" target="_blank"&gt;example page which uses these functions&lt;/a&gt;. I'll explain the details of the code on that page here.&lt;br /&gt;&lt;br /&gt;First there is the number only field&lt;br /&gt;&lt;br /&gt;&amp;lt;input type="text" name="num" onchange="if(!IsNumber(this,1,100)) { this.value = 1; Highlight(this,'red'); } else { Highlight(this,''); }" /&amp;gt;&lt;br /&gt;&lt;br /&gt;the code in the onchange event first uses the IsNumber function to see if the value in the field is between 1 and 100. As there's the ! in front, the if is true when the value is NOT a number.&lt;br /&gt;&lt;br /&gt;If the value isn't a number between 1 and 100, it sets the fields value to 1 with this.value = 1. Then it uses the Highlight function to highlight the field in red.&lt;br /&gt;&lt;br /&gt;The else segment runs when the value is a number between 1 and 100. The only thing we do there is set the background color of the field to '' which in this case is the default "no color" value. We need it because the fields background might be red if the user had inputted an incorrect value first, so when he inputs a correct one the background will stop being red.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Next there's a textarea which allows only 20 characters. As you can see from this, these functions also work on textareas.&lt;br /&gt;&lt;br /&gt;&amp;lt;textarea rows="5" onkeyup="MaxSize(this,20)"&amp;gt;Max 20 chars!&amp;lt;/textarea&amp;gt;&lt;br /&gt;&lt;br /&gt;This one is very simple. When the user has typed in a key, it just uses MaxSize to crop the length if it's over 20 characters.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Lastly, the email field.&lt;br /&gt;&lt;br /&gt;&amp;lt;input type="text" value="only.valid@email.com" onchange="if(!IsEmail(this)) { Highlight(this,'red'); } else { Highlight(this,''); }"/&amp;gt;&lt;br /&gt;&lt;br /&gt;This one is pretty similar to the number only one. The field gets a red background if the value is not a valid email address.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There's one thing, however, which isn't demosntrated on that page but is quite important. It's the empty field check. You should do this when the user presses the submit button on the form.&lt;br /&gt;&lt;br /&gt;Here's how it works:&lt;br /&gt;&lt;br /&gt;First, set the onsubmit event of the form..&lt;br /&gt;&amp;lt;form ... id="myform" onsubmit="return FormCheck()"&amp;gt;&lt;br /&gt;&lt;br /&gt;then create a function called FormCheck&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function FormCheck()&lt;br /&gt;{&lt;br /&gt; //First, get the form element&lt;br /&gt; var f = document.getElementById('myform');&lt;br /&gt;&lt;br /&gt; //Now we can easily check values in fields like this&lt;br /&gt; if(f.fieldName.value == '')&lt;br /&gt; {&lt;br /&gt;  Highlight(f.fieldName,'red');&lt;br /&gt;&lt;br /&gt;  //if we return false, the form won't be submitted&lt;br /&gt;  //so the user can fix his errors&lt;br /&gt;  return false;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; //if all was ok, return true so the form gets submitted&lt;br /&gt; return true;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Checking if a field is empty is simple as you can see from that. Notice how I defined the form an ID so I can use the getElementById function there. Accessing inputs in a form is very simple after you have the form element, just put the fields name there as shown in the code.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As you can see, checking forms like that is very simple with JavaScript, yet it's not used almost at all. I wonder why...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115649559692948039?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115649559692948039/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115649559692948039' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115649559692948039'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115649559692948039'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/08/form-validation-with-js.html' title='Form validation with JS'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115614555330917155</id><published>2006-08-21T09:48:00.000+03:00</published><updated>2006-08-21T10:32:33.496+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><title type='text'>Moving settings over from an old widget to a new one</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;&lt;br /&gt;In Opera Widgets you can save settings using the widget.setPreferenceForKey method. It's very useful, but there's a small flaw in the design.&lt;br /&gt;&lt;br /&gt;When you release a new version of your widget, the user must download the new version of the widget and they usually have to reconfigure it as the preferences you stored in the old widget do not move over to the new one.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's a very simple method to move the settings over from the old version to the new version. It's not completely automatic, but it shouldn't be too difficult or troublesome for the user.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;First&lt;/b&gt;, you need a field in the widget. It can be an input or a textarea. This will be used to display the widgets internal data for the preferences so the user can copy it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Getting the data to the field is very simple. You can use the &lt;a href="http://zeeohemgee.blogspot.com/2006/08/serialization-of-javascript-objects.html"&gt;JavaScript object serializer&lt;/a&gt; I introduced in an earlier post to create a text version of the array or the object you use to store the settings.&lt;br /&gt;&lt;br /&gt;If you don't use an object or an array to store the settings, I'd recommend you start using one because it simplifies things a lot if there's much data.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Second&lt;/b&gt;, you need a button for loading the data in the field. This is used to have the widget load the data in the field.&lt;br /&gt;&lt;br /&gt;The way this works is that the user has both the new and old version running, he goes to the field in the old one, copies the data there and pastes it into the new one and presses the load button. The new version then just uses the data in the field and loads itself instead of using the data stored in the widget.preferenceForKey thing. Simple huh?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I also wrote a small example widget to demonstrate the idea. &lt;a href="http://admins.fi/~eagleeye/articles/settings_migration/config.zip"&gt;Grab it from here&lt;/a&gt;. If it doesn't run as a widget, just load it from File-&amp;gt;Load.&lt;br /&gt;&lt;br /&gt;Put some values to the two value fields, press save. Then it should reload the widget and display the data string in the first field. You can then copy that and set some new values in the two value fields and save again.&lt;br /&gt;&lt;br /&gt;Then just paste the string you copied from the first field back to the first field and press load... you should see how the two fields below revert to what they were when you copied the string :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As usual, if anything was unclear or you have any questions, ask away!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115614555330917155?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115614555330917155/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115614555330917155' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115614555330917155'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115614555330917155'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/08/moving-settings-over-from-old-widget.html' title='Moving settings over from an old widget to a new one'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115604617213339097</id><published>2006-08-20T06:54:00.000+03:00</published><updated>2006-08-20T06:56:12.143+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tutorial'/><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Intermediate C# Concepts</title><content type='html'>&lt;adsense&gt;&lt;/adsense&gt;&lt;br /&gt;Here's my second C# article, intermediate C# concepts. This article explains some more C# concepts after the introduction article. In the end you'll have a simple text editor a bit like notepad. Topics covered include more about classes, arrays and lists, creating controls run-time with code etc.&lt;br /&gt;&lt;br /&gt;Again, due to some limitations in the blogger system I'm hosting it elsewhere. Please post comments, questions or anything about it to here.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://admins.fi/~eagleeye/articles/csinter.php"&gt;Read the article&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115604617213339097?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115604617213339097/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115604617213339097' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115604617213339097'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115604617213339097'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/08/intermediate-c-concepts.html' title='Intermediate C# Concepts'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115568465941665725</id><published>2006-08-16T01:50:00.000+03:00</published><updated>2006-08-16T02:30:59.636+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><title type='text'>Serialization of JavaScript objects</title><content type='html'>In the &lt;a href="http://widgets.opera.com/widget/4648" target="_blank"&gt;widget I'm working on&lt;/a&gt; I have to save the users preferences and settings. In Opera Widgets, this can be done by using a JavaScript function widget.setPreferenceForKey which can be used to store strings with keys.&lt;br /&gt;&lt;br /&gt;I had written a function in my Clock-class which made a string of its data, like the name, GMT offset, GMT minute offset, DST settings etc.&lt;br /&gt;&lt;br /&gt;As you can see, there's quite a lot of things already on that list. I started to getting into trouble when I started working on alerts.&lt;br /&gt;&lt;br /&gt;I wanted to save the alerts to each clock, so I would've had to write even more code to get a string of the clock, which I just found a bit stupid. In PHP you have a Serialize() function which creates a string of an object or an array, which I thought would be very useful to have in JavaScript as well for purproses like this.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So I coded my own Serialize() and Unserialize() functions for JS!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How it works&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The Serialize-function takes an object or an array as its parameter and returns a string representation of it, which can be then given to Unserialize() along with a base-object and you get an object with the same properties as when Serialized.&lt;br /&gt;&lt;br /&gt;For a simple array, the serialize output might look like this:&lt;br /&gt;&lt;br /&gt;s:0:5:Hello:n:1:2:20:s:2:14:I'm the cell 2&lt;br /&gt;&lt;br /&gt;The above data would result in an array as follows:&lt;br /&gt;&lt;br /&gt;Array[0] = "Hello";&lt;br /&gt;Array[1] = 20;&lt;br /&gt;Array[2] = "I'm the cell 2";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So how exactly is that converted into an obscure string like that?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Serialize() -code&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//JavaScript object serializer&lt;br /&gt;// Returns a string representation of an object&lt;br /&gt;function Serialize(o)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; //The serialized data is stored here&lt;br /&gt; var data = '';&lt;br /&gt;&lt;br /&gt; //It's an array if o.length is defined&lt;br /&gt; //Arrays must be enumereated differently than&lt;br /&gt; //other objects, so the check has to be made&lt;br /&gt; if(o.length)&lt;br /&gt; {&lt;br /&gt;  //Array-mode&lt;br /&gt;  &lt;br /&gt;  for(var i = 0; i &lt; o.length; i++)&lt;br /&gt;  {&lt;br /&gt;   ParseProp(i); &lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; else&lt;br /&gt; {&lt;br /&gt;  //Object-mode&lt;br /&gt;  &lt;br /&gt;  for(property in o)&lt;br /&gt;  {   &lt;br /&gt;   ParseProp(property);&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; //strip : from end&lt;br /&gt; data = data.substr(0,(data.length-1)); &lt;br /&gt; &lt;br /&gt; return data;&lt;br /&gt; &lt;br /&gt; //Internal function which parses the properties&lt;br /&gt; function ParseProp(p)&lt;br /&gt; {&lt;br /&gt;  //Functions aren't serialized&lt;br /&gt;  if(typeof o[p] != 'function')&lt;br /&gt;  {     &lt;br /&gt;   switch(typeof o[p])&lt;br /&gt;   {&lt;br /&gt;    //If property is a number&lt;br /&gt;    case 'number':&lt;br /&gt;     //Convert to string and find length&lt;br /&gt;     var len = String(o[p]).length;&lt;br /&gt;     data += 'n:'+p+':'+len+':'+o[p];&lt;br /&gt;     break;&lt;br /&gt;     &lt;br /&gt;    //if prop is a string&lt;br /&gt;    case 'string':&lt;br /&gt;     var len = o[p].length;&lt;br /&gt;     data += 's:'+p+':'+len+':'+o[p];&lt;br /&gt;     break;&lt;br /&gt;    &lt;br /&gt;    //If prop is bool&lt;br /&gt;    case 'boolean':&lt;br /&gt;     var b = (o[p]) ? 1 : 0;&lt;br /&gt;     data += 'b:'+p+':'+b;&lt;br /&gt;     break;&lt;br /&gt;    &lt;br /&gt;    //If prop is another object&lt;br /&gt;    case 'object':&lt;br /&gt;     //Run a serialize on the child-object&lt;br /&gt;     var objdata = Serialize(o[p]);&lt;br /&gt;     var len = objdata.length; //take data length&lt;br /&gt;&lt;br /&gt;     //Find the type of the object from its constructor&lt;br /&gt;     var type = o[p].constructor.toString();&lt;br /&gt;&lt;br /&gt;     //Find location of the constructors name&lt;br /&gt;     var sindex = type.indexOf(' ') + 1;&lt;br /&gt;     var sindex2 = type.indexOf('(');&lt;br /&gt;     &lt;br /&gt;     //Extract the name of the constructor&lt;br /&gt;     type = type.substring(sindex,sindex2);&lt;br /&gt;     &lt;br /&gt;&lt;br /&gt;     data += 'o:'+type+':'+p+':'+len+':'+objdata;&lt;br /&gt;     break;&lt;br /&gt;    &lt;br /&gt;   }&lt;br /&gt;   data += ':';&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There we go. So firstly, the code checks whether the object is an array. Arrays require a bit different approach to enumerating through its properties as seen in the code.&lt;br /&gt;&lt;br /&gt;The ParseProp function inside the Serialize does most of the work. It parses the properties of the object into strings. First, it uses typeof to check if the property is not a function, as we don't want to serialize functions.&lt;br /&gt;&lt;br /&gt;Then we continue to a switch statement to parse the different types.&lt;br /&gt;&lt;br /&gt;Numbers and strings are parsed in almost the same way: we find its length by converting it into a string using String() and its .length property. Then its saved into the data-block. n is the key for Number type, after which comes the name of the property and after that the length and finally the value.&lt;br /&gt;&lt;br /&gt;Strings only differ that we don't need to convert them to find the length. Their key is s.&lt;br /&gt;&lt;br /&gt;Boolean variables (true/false) are saved into the datastring, depending on their state, as either 0 or 1 to save space.&lt;br /&gt;&lt;br /&gt;The object parser is probably the most complicated here. First, it serializes the child-object using a recursive call to Serialize(). Then it finds the length of the serialized data.&lt;br /&gt;It also has to find the type of the object, which we can find from the objects constructor with a bit of string manipulation: as the constructor looks like "function Name() { some code here }", we just take the first location of a space and the first location of a ( to find the Name part and save it.&lt;br /&gt;&lt;br /&gt;The object notation in the data goes like this: o is the key for the object, then comes the type name, property name, data length and the actual data.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;All of the data are appended with a : if we later need to add more properties to the string, so after all props have been parsed, we simply remove the last character from the data and return it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Unserialize() -code&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//JavaScript object unserializer&lt;br /&gt;// Returns an object from the serialized data&lt;br /&gt;function Unserialize(data,o)&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; //Invalid Serialize-data. Should begin with s,b,o or n&lt;br /&gt; if(data[0] != 's' &amp;&amp; data[0] != 'b' &amp;&amp; data[0] != 'o' &amp;&amp; data[0] != 'n')&lt;br /&gt;  return o;&lt;br /&gt; &lt;br /&gt; var i; //Counter defined here so it's accessible from GetNextString&lt;br /&gt; &lt;br /&gt; for(i = 0; i &lt; data.length; i++)&lt;br /&gt; {&lt;br /&gt;  var mode = GetNextString(); //Get mode&lt;br /&gt;&lt;br /&gt;  var d = null; //stores the final prop&lt;br /&gt;  var propname; //stores name of the prop&lt;br /&gt;  if(mode == 's')&lt;br /&gt;  {&lt;br /&gt;   //string-mode&lt;br /&gt;   &lt;br /&gt;   propname = GetNextString();&lt;br /&gt;   //Find next delimiter&lt;br /&gt;&lt;br /&gt;   var len = Number(GetNextString());&lt;br /&gt;   //Extract data&lt;br /&gt;   d = data.substr(i,len);&lt;br /&gt;   &lt;br /&gt;   //i is incremented in the end, otherwise we'd have&lt;br /&gt;   //to go forward datalength + 1 here!&lt;br /&gt;   i += len; //advance pointer&lt;br /&gt;  }&lt;br /&gt;  else if(mode == 'n')&lt;br /&gt;  {&lt;br /&gt;   //Number mode&lt;br /&gt;   propname = GetNextString();&lt;br /&gt;   var len = Number(GetNextString());&lt;br /&gt;   d = Number(data.substr(i,len));&lt;br /&gt;   i += len;&lt;br /&gt;  }&lt;br /&gt;  else if(mode == 'b')&lt;br /&gt;  {&lt;br /&gt;   propname = GetNextString();&lt;br /&gt;   &lt;br /&gt;   d = (data[i] == 1) ? true : false; &lt;br /&gt;   &lt;br /&gt;   //i is incremented in the end, otherwise we'd have&lt;br /&gt;   //to go forward + 2 here!&lt;br /&gt;   i++; //pointer forward&lt;br /&gt;  }&lt;br /&gt;  else if(mode == 'o')&lt;br /&gt;  {&lt;br /&gt;   var type = GetNextString();&lt;br /&gt;   propname = GetNextString();&lt;br /&gt;   var len = Number(GetNextString());&lt;br /&gt;   var odata = data.substr(i,len);   &lt;br /&gt;&lt;br /&gt;   //We need to use eval to create a new&lt;br /&gt;   //instance of "type"&lt;br /&gt;   eval('d = new '+type);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;   d = Unserialize(odata,d);&lt;br /&gt;&lt;br /&gt;   i += len;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  //Save&lt;br /&gt;  o[propname] = d;&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; return o;&lt;br /&gt; &lt;br /&gt; //this is used to get data from the datastring&lt;br /&gt; function GetNextString()&lt;br /&gt; {&lt;br /&gt;  var n = data.indexOf(':',i);&lt;br /&gt;  &lt;br /&gt;  //Extract property name&lt;br /&gt;  var strdata = data.substring(i,n);&lt;br /&gt;&lt;br /&gt;  i += strdata.length + 1; //advance pointer&lt;br /&gt;  &lt;br /&gt;  return strdata;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now this is a bit more complicated than the Serialize() function. You have to pass the serialized data as a parameter and an object which is used to save the props from the serialized data. So if you had an serialized array, the object has to be an array.&lt;br /&gt;&lt;br /&gt;First, there's a check to determine whether the serialized data is ok. This is done by checking whether it starts with one of the keys used for different datatypes. Not absolutely necessary, but I think it's a good thing to have.&lt;br /&gt;&lt;br /&gt;The &lt;i&gt;i&lt;/i&gt; variable is defined before the for this time, so GetNextString can access it. GetNextString is just something which simplifies a few string operations, so I don't have to write a substring call and an i+=length call every time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;We loop until we have reached the end of the data. First, we get the mode (n for number, s for string, b for bool, o for object) from the data.&lt;br /&gt;&lt;br /&gt;Parsing strings is pretty simple. The propertys name and length are taken from the data to be able to use substr to extract the actual data.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note: we can't use GetNextString to extract the actual data! If there's a : in the data, things will screw up, so that's why we also store the data length.&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Parsing numbers is pretty much the same as for strings, we just use Number() to convert the data into a number.&lt;br /&gt;&lt;br /&gt;Boolean parsing is even more simple, as it only takes one character after the initial prop name.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, the object parser is yet again a bit more complicated as expected.&lt;br /&gt;&lt;br /&gt;First we find the type name, prop name, data length and the data from the serialized data. Then we use eval() to create a new instance of the type stored in the variable. After this it's just a matter of a recursive Unserialize call and we're done.&lt;br /&gt;&lt;br /&gt;After the if-section, the property is saved into the object. Finally the new object is returned.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Wrap up&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Using this method to save data is pretty simple:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var a = new Array('Example',true,'Yes sire',1234);&lt;br /&gt;var data = Serialize(a); //store a to a string&lt;br /&gt;&lt;br /&gt;var newArray = new Array();&lt;br /&gt;newArray = Unserialize(data,newArray);&lt;br /&gt;//now newArray contains the same things as a&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There are, however, some things to note:&lt;br /&gt;&lt;br /&gt;In custom objects, only the variables defined with &lt;i&gt;this&lt;/i&gt; are saved! Take this into account when working with this. I'm not sure if there's a method to save private members as well, so if you know a better method of going through the properties, please post a comment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115568465941665725?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115568465941665725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115568465941665725' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115568465941665725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115568465941665725'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/08/serialization-of-javascript-objects.html' title='Serialization of JavaScript objects'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115551426937243283</id><published>2006-08-14T02:54:00.000+03:00</published><updated>2006-08-14T03:15:09.680+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='widgets'/><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><title type='text'>Opera Widgets: Imitating alert() behavior using a custom object</title><content type='html'>As I've been tinkering around a lot with widgets, I've sometimes needed a function like the alert() in JavaScript, ie. something which can be used to display a message to the user.&lt;br /&gt;&lt;br /&gt;In this post, I'll go over my MessageBox class, which can be used for just that.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The idea behind it all&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Idea is to make showing alert boxes as simple as possible, while still giving some functionality to the user. As it's not possible to use alert() in Opera Widgets, you need to code this yourself. I also wanted to be able to either display timed boxes which would disappear after a certain time in addition to "normal" ones with an OK button.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Give me the code!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//Displays a generic textbox in the style of alert&lt;br /&gt;//w = width, h = height, rOK = require the press of OK button to close&lt;br /&gt;function MessageBox(w,h,rOK)&lt;br /&gt;{&lt;br /&gt; var element = null;&lt;br /&gt; var width = w&lt;br /&gt; var height = h;&lt;br /&gt; var left = 30;&lt;br /&gt; var top = 10;&lt;br /&gt; var requireOK = rOK;&lt;br /&gt; &lt;br /&gt; //shows the messagebox&lt;br /&gt; //msg = message in the box, time = time how long the message remains visible&lt;br /&gt; //note: if requireOK is true, the box won't close until OK is pressed&lt;br /&gt; this.Show = function(msg,time)&lt;br /&gt; {&lt;br /&gt;  element = document.createElement('div');&lt;br /&gt;  element.style.left = left+'px';&lt;br /&gt;  element.style.top = top+'px';&lt;br /&gt;  element.style.width = width+'px';&lt;br /&gt;  element.style.minHeight = height+'px';&lt;br /&gt;  element.style.border = '1px solid black';&lt;br /&gt;  element.style.backgroundColor = 'white';&lt;br /&gt;  element.style.position = 'absolute';&lt;br /&gt;  element.style.textAlign = 'center';&lt;br /&gt;&lt;br /&gt;  element.innerHTML = msg+'&amp;lt;br /&amp;gt;&amp;lt;br /&amp;gt;';&lt;br /&gt;  &lt;br /&gt;  if(requireOK)&lt;br /&gt;  {&lt;br /&gt;   var okbutton = document.createElement('button');&lt;br /&gt;   okbutton.text = 'OK';&lt;br /&gt;   okbutton.addEventListener('click',function() { Hide(); },false);&lt;br /&gt;   element.appendChild(okbutton);&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  document.appendChild(element);&lt;br /&gt;  if(!requireOK) setTimeout("Hide()",time);&lt;br /&gt;  &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; Hide = function()&lt;br /&gt; {&lt;br /&gt;  document.removeChild(element);&lt;br /&gt;  element = null;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;There we go. There's not much to explain if you already know JS and DOM, but let's go through it a bit for those who don't.&lt;br /&gt;&lt;br /&gt;We define some variables to hold various data on the messagebox. The element variable will store the reference to the actual div we use to display the messagebox, which is needed so we can hide it later. Rest of them are probably obvious, except requireOK, which is used to check whether we want to display an OK button on the messagebox or not.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Show function is used to display the box. First we create a div element to hold the message and change some of its CSS properties. We use absolute positioning to make the div appear exactly where we want and ignore the positions of the other elements. We also add the message user wants the box to show to its innerHTML.&lt;br /&gt;&lt;br /&gt;If the requireOK is defined as true, the code creates a new button element and assigns it a click event which calls the Hide function. Finally the button is added to the base div with appendChild.&lt;br /&gt;&lt;br /&gt;After this, the div is appended to the document and if we don't have an OK button, a timeout is set to hide the box after the time the user specified in the parameter.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The Hide function is quite simple: we simply use document.removeChild to remove the messagebox div element from the document.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Using the class is simple:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var message = new MessageBox(100,100,true);&lt;br /&gt;message.Show("Hello World!",0);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This would display a 100x100 messagebox with text "Hello World!". It closes when the user presses the OK button displayed on the box. Simple and fun.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Wrapping it up&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Using classes like this is a good way to add reusable functionality to widgets. This one for example can be used in all widgets you want, instead of possible static code in a single widget which would do the same. Sure, the static one could be faster and easier to code... but what would be the fun in that? :)&lt;br /&gt;&lt;br /&gt;There are some things that could be added to this class, however. Someone might want to be able to change the position or the colors of the box, so functionality for that could be added if necessary.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115551426937243283?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115551426937243283/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115551426937243283' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115551426937243283'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115551426937243283'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/08/opera-widgets-imitating-alert-behavior.html' title='Opera Widgets: Imitating alert() behavior using a custom object'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115550685388632901</id><published>2006-08-14T00:24:00.000+03:00</published><updated>2006-08-14T01:07:33.996+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='sample'/><title type='text'>More Object-Oriented JavaScript</title><content type='html'>Here's some more stuff related to OO-JavaScript&lt;br /&gt;&lt;br /&gt;&lt;b&gt;How to create a function which is both callable from inside the class and from outside?&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;This had caused me some problems up to now... I wasn't able to make a function inside a class work from both inside the class and from outside. Here's how to "properly" create one of those:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function Example()&lt;br /&gt;{&lt;br /&gt;  this.FunctionName = InternalFunctionName&lt;br /&gt;&lt;br /&gt;  function InternalFunctionName()&lt;br /&gt;  {&lt;br /&gt;    // do something funky&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the above example, the InternalFunctionName function is callable with that name from &lt;i&gt;inside&lt;/i&gt; the class. From &lt;i&gt;outside&lt;/i&gt;, the same function is callable with the name FunctionName. Of course they can both share the same name, the different name was just for the sake of the example.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Expanding objects&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;In JavaScript, you can easily expand objects/classes which already exist. For example, you can add a function to the built-in Array object.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;Array.prototype.SayHello = function() &lt;br /&gt;{&lt;br /&gt;  alert('hello');&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;After doing that, all Array objects can show you an alert box containing text Hello. Yeah, it's pretty useless but it works as an example. You could take the CopyArray and Equals functions from &lt;a href="http://zeeohemgee.blogspot.com/2006/07/comparing-and-copying-arrays-in.html"&gt;my post about comparing and copying arrays in JS&lt;/a&gt; and add those if you wanted something useful.&lt;br /&gt;&lt;br /&gt;You can also add functions to already existing instances, which isn't very useful but possible&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;var s = new SomeClass();&lt;br /&gt;s.DoSomething = function()&lt;br /&gt;{&lt;br /&gt;  //do something&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Inheriting from a base-class&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To inherit from a base-class, do the following&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function BaseClass()&lt;br /&gt;{&lt;br /&gt;  function A()&lt;br /&gt;  {&lt;br /&gt;    //something&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function OtherClass()&lt;br /&gt;{&lt;br /&gt;  //inherit from BaseClass&lt;br /&gt;  this.prototype = BaseClass.prototype;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;This would make OtherClass get function A from BaseClass. Very simple, but the syntax is probably a bit different from what it usually is.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115550685388632901?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115550685388632901/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115550685388632901' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115550685388632901'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115550685388632901'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/08/more-object-oriented-javascript.html' title='More Object-Oriented JavaScript'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115543594673896027</id><published>2006-08-13T05:16:00.000+03:00</published><updated>2006-08-13T05:25:46.750+03:00</updated><title type='text'>World goes 'round</title><content type='html'>Been starting on school again here... not many courses though... one. Dealing with MS SQL Server, which I already am pretty comfortable with. In addition to that, I need to do some exams, but I'm expecting an easy fall term.&lt;br /&gt;&lt;br /&gt;I've been writing some articles on C#. As you can see from the previous post dealing with introduction to C#. The next ones in the series are in the works and I can hopefully get them up sometime soon~ish. I'm also been tinkering with some localization (adding multiple language support to an app) issues, so you can look forward to an in-depth look into that as well!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For my projects, I've been starting work on some website work for a LAN Party and an accounting application. I also need to continue my game development, as I'm intending on doing my scholarly thesis on that project. Maybe some posts on those subjects here. Not forgetting the JavaScript, of course... the World Clocks -widget is still pretty fun and intresting so I'll probably write about some things related to JS developement too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;But now I think I'm going to catch some sleep. Later!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115543594673896027?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115543594673896027/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115543594673896027' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115543594673896027'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115543594673896027'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/08/world-goes-round.html' title='World goes &apos;round'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115497981193388062</id><published>2006-08-07T22:37:00.000+03:00</published><updated>2006-08-07T22:48:27.296+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Introduction to C#</title><content type='html'>I've written an introductionary article to the programming language C#.&lt;br /&gt;&lt;br /&gt;The article introduces you to the C# programming language and the Visual Studio developement environment. Topics covered include basics about classes, Windows applications, error handling etc. You should preferably have some past programming experience, but you might make something even if you don't.&lt;br /&gt;&lt;br /&gt;Please post any comments, questions and feedback to this post.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://admins.fi/~eagleeye/articles/csintro.php"&gt;Read the article: Introduction to C#&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115497981193388062?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115497981193388062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115497981193388062' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115497981193388062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115497981193388062'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/08/introduction-to-c.html' title='Introduction to C#'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115468823191526738</id><published>2006-08-04T13:43:00.000+03:00</published><updated>2006-08-18T17:26:53.180+03:00</updated><title type='text'>Implementing automatic version checking in an Opera Widget</title><content type='html'>&lt;b&gt;Updated August 18th, fixed an issue with the source code which causes a lockup if you're not connected to the internet when the update check runs&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As I've been working on my Opera widget World Clocks, I've done a bunch of version updates with new features and such. Of course people might not come back to the download page to check if there's anything new, so it would be useful to be able to tell them automatically when you have a new version available.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So I went and added an automatic new version check, and now I'll tell you how to create one as well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Preparing the widget&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Okay, for the Widget to know when there's a new version you need something to compare. What's better than having a variable store the version of the widget?&lt;br /&gt;&lt;br /&gt;var widgetVersion = "1.0";&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And what do we compare that with? Let's save a file somewhere on the internet, with the current version of the Widget. For example, I put the current version of my clock widget to &lt;a href="http://admins.fi/~eagleeye/clockversion.txt" target="_blank"&gt;here&lt;/a&gt;. As you can see, it's just a number.&lt;br /&gt;&lt;br /&gt;To allow our widget to access a page in the internet, we must add this to the config.xml file:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;security&amp;gt;&lt;br /&gt; &amp;lt;access&amp;gt;&lt;br /&gt;  &amp;lt;protocol&amp;gt;http&amp;lt;/protocol&amp;gt;&lt;br /&gt;  &amp;lt;host&amp;gt;admins.fi&amp;lt;/host&amp;gt;&lt;br /&gt; &amp;lt;/access&amp;gt;&lt;br /&gt;&amp;lt;/security&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;For example, my file is at http://admins.fi/~eagleeye/clockversion.txt, so I set the protocol as http and host to admins.fi.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Creating the update checker&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;To access that page, we will use the XMLHttpRequest object. For the sake of reusability, let's make our object a bit better than just some code accessing a static page... let's make it reusable in other projects as well!&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//parameters:&lt;br /&gt;//vurl: the url where the file to compare is&lt;br /&gt;//cver: current version of the widget&lt;br /&gt;//callback: the function to call when a new version is out&lt;br /&gt;function UpdateChecker(vurl,cver,callback)&lt;br /&gt;{&lt;br /&gt; var checkUrl = vurl;&lt;br /&gt; var currentVersion = cver;&lt;br /&gt; call = callback;&lt;br /&gt;&lt;br /&gt; //this function checks for the update&lt;br /&gt; this.Check = function()&lt;br /&gt; {&lt;br /&gt;  var req = new XMLHttpRequest();&lt;br /&gt;  req.onreadystatechange = function()&lt;br /&gt;  {&lt;br /&gt;   if(req.readyState == 4) &lt;br /&gt;   {&lt;br /&gt;    //simply compare the page to the version number&lt;br /&gt;    if(req.responseText != currentVersion)&lt;br /&gt;     call();&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;  req.overrideMimeType('text/plain');&lt;br /&gt;  &lt;br /&gt;  //the random part is used to bypass Operas caching.&lt;br /&gt;  //sometimes the page stays in cache and wont be updater properly&lt;br /&gt;  req.open('GET',checkUrl+'?random='+Math.random(), true);&lt;br /&gt;&lt;br /&gt;  try&lt;br /&gt;  {&lt;br /&gt;   req.send(null);&lt;br /&gt;  }&lt;br /&gt;  catch (e)&lt;br /&gt;  {&lt;br /&gt;   //problem connecting&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;it's a very simple XMLHttpRequest function there. To use it, we could do...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;br /&gt;function Init()&lt;br /&gt;{&lt;br /&gt; var updater = new UpdateChecker('http://site.com/ver.txt','2.0',newVersion);&lt;br /&gt; updater.Check();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function newVersion()&lt;br /&gt;{&lt;br /&gt; //put some code here&lt;br /&gt; //which tells the user&lt;br /&gt; //that a new version is out&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Simple as that. I'm not going to go into details about using XMLHttpRequest here, there's a very good article at &lt;a href="http://developer.mozilla.org/en/docs/AJAX:Getting_Started" target="_blank"&gt;http://developer.mozilla.org/en/docs/AJAX:Getting_Started&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115468823191526738?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115468823191526738/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115468823191526738' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115468823191526738'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115468823191526738'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/08/implementing-automatic-version.html' title='Implementing automatic version checking in an Opera Widget'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115405435630467815</id><published>2006-07-28T05:39:00.000+03:00</published><updated>2006-07-28T05:40:52.903+03:00</updated><title type='text'>Who said a format/reinstall is the only option?</title><content type='html'>I wonder how many times in the past I have reinstalled Windows 95, 98, and 98SE because something screwed things up. You probably have done that as well.&lt;br /&gt;&lt;br /&gt;Many people kept on reinstalling Windows after MS launched 2000 and even XP, even though they had excellent recovery and repair tools and lost much files and data. Even for minor things like a new graphics card.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I have used Windows 2000 Professional for years. Never had to reinstall it or format the drive. The computer even went through a complete rebuild! Only the harddisk was swapped from the old, and it still kept going! Whoever said Windows isn't stable doesn't know crap about it.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;When I switched to XP, I didn't know it would require me to install a patch, namely Service Pack 2, to support big disks like the 200 gig disk I have. It screwed up the partition table on the disk and there went my 200 gigs of data, including the installation of the Windows.&lt;br /&gt;&lt;br /&gt;Back then, I used GetDataBack for NTFS to restore my important files. It was a pretty good tool, although some files got a bit corrupted.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now the disk flattened the partition table. Again. I don't know why, but it happened.&lt;br /&gt;This time I had more important files and didn't want to risk any corruption because it was honestly said pretty annoying.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The Ultimate tools for Windows system recovery&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Starting from the &lt;b&gt;Recovery Console&lt;/b&gt; on Windows' XP and 2000 disc. It lets you do basic operations in a DOS-like environment like copying and renaming files on the disk. It also lets you fix the boot sector and Master Boot Record (MBR) which is very useful in some situations.&lt;br /&gt;&lt;br /&gt;The second tool for recovering a dead system is of course &lt;b&gt;The Ultimate Boot CD&lt;/b&gt;. It has a big batch of useful tools ranging from disk formatting utilities to antivirus. There is a very useful tool on the disk called &lt;i&gt;TestDisk&lt;/i&gt; which recovers lost partitions. In my case I had two partitions on the 200 gig disk and all I had to do to get them back was boot into UBCD, choose TestDisk, select the 200 gig disk as the target drive and it would do the rest on it's own, only asking me for confirmation or possible changes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And now let's continue the story for a short moment: after recovering the partitions with TestDisk, I tried to boot back into Windows. Windows XP would start loading... then it would give me the sign in prompt. I thought that was it... until I noticed the keyboard and mouse didn't react to my input! &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This time firing up the recovery console, I went into c:\windows\system32\config and backed up system from that dir. Then I copied over c:\windows\rescue\system to the config dir. Back to Windows again... thinking "Did Windows move to C... don't tell me it did.". You see, I had Windows on drive F! I knew it would cause me problems if it had moved to the letter C...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Back to windows again. The keyboard works, mouse didn't. Well, whatever, let's just sign in!&lt;br /&gt;Waiting a while for the things to load... hey wait, why am I being logged out?&lt;br /&gt;I was logged out automatically every time I tried to log in. No matter which user I tried. Same thing happened in Safe Mode as well.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I googled around a bit and found out this could be caused by a file called userinit.exe being looked for from the wrong place. hmm. C:\Windows\userinit.exe... F:\Windows\userinit.exe... See the problem?&lt;br /&gt;&lt;br /&gt;and now comes in the third tool for ultimate system recovery!&lt;br /&gt;&lt;b&gt;The Ultimate Boot CD &lt;i&gt;for Windows&lt;/i&gt;!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Creating this baby required some help from my buddy, thanks to him. It contains a Windows pre-install environment loaded with recovery and diagnostics tools.&lt;br /&gt;A windows pre-install environment is a shell like Windows so it's pretty easy to use as well.&lt;br /&gt;&lt;br /&gt;Now, to fix the partition letters to the correct order!&lt;br /&gt;First I fire up regedit and explorer for the pre-install windows. I check which drive is which from explorer and go to HKEY_LOCAL_MACHINE\SYSTEM\MountedDevices and make a dump of that and open it in notepad.&lt;br /&gt;&lt;br /&gt;After this, I opened the Remote Registry Editor on the desktop which lets me edit the registry on the actual windows installation on the harddisk.&lt;br /&gt;&lt;br /&gt;I went again to the mounted devices hive in the registry and started looking how the \DosDevices\X: entries were labeled... I renamed them so the drive letters there would match the order they should be in Windows... \DosDevices\C: goes to \DosDevices\F: and so on. Pretty simple stuff.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Okay now I was done. Time to see what happens when I boot to windows!&lt;br /&gt;&lt;br /&gt;and... it worked!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anyway, all in all this took really really many hours to accomplish. Why? Because I didn't have the tools around. If I had had them, it wouldn't have taken very long to fix all this. So.. the next time you encounter a problem... think a bit before formatting, you might learn something in the process, even if you can't fix the problem!&lt;br /&gt;&lt;br /&gt;Here are links to the tools I mentioned:&lt;br /&gt;&lt;a href="http://www.ultimatebootcd.com/" target="_blank"&gt;The Ultimate Boot CD&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ubcd4win.com" target="_blank"&gt;The Ultimate Boot CD for Windows&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115405435630467815?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115405435630467815/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115405435630467815' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115405435630467815'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115405435630467815'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/07/who-said-formatreinstall-is-only.html' title='Who said a format/reinstall is the only option?'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115355933793647141</id><published>2006-07-22T11:45:00.000+03:00</published><updated>2006-07-22T12:28:16.420+03:00</updated><title type='text'>Comparing and copying arrays in JavaScript is a pain</title><content type='html'>Ever wanted to copy an array in JavaScript? Tried the simple var array2 = array1?&lt;br /&gt;Yes, it doesn't work that way.&lt;br /&gt;&lt;br /&gt;Apparently with arrays and objects, JS uses references just like C# and in case you want to make a copy of an array...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function CopyArray(a)&lt;br /&gt;{&lt;br /&gt;  //Create a new array with the old ones length&lt;br /&gt;  var n = new Array(a.length);&lt;br /&gt;&lt;br /&gt;  //Just copy all the values from the old to the new&lt;br /&gt;  for(var i = 0; i &lt; a.length; i++)&lt;br /&gt;    n[i] = a[i];&lt;br /&gt;  &lt;br /&gt;  return n;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;var array2 = CopyArray(array1);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You'll have to use something like that. Of course it gets way more complicated when dealing with jagged arrays, eg. arrays which have arrays in them. You'll have to write a recursive function or something the like of this:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function CopyArray(a)&lt;br /&gt;{&lt;br /&gt;  //Create a new array with the old ones length&lt;br /&gt;  var n = new Array(a.length);&lt;br /&gt;&lt;br /&gt;  //Just copy all the values from the old to the new&lt;br /&gt;  for(var i = 0; i &lt; a.length; i++)&lt;br /&gt;  {&lt;br /&gt;    //if the value in the old array is an object (array)&lt;br /&gt;    //call the CopyArray function recursively&lt;br /&gt;    if(typeof a[i] == 'object')&lt;br /&gt;      n[i] = CopyArray(a[i]);&lt;br /&gt;    else&lt;br /&gt;      n[i] = a[i];&lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  return n;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With that you can create nice copies of arrays while still keeping them as array objects.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;How about comparing arrays? Uh oh, if(a == b) doesn't work like expected!&lt;br /&gt;&lt;br /&gt;Yet again we'll have to use a customized function&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//Check if two arrays' contents are the same&lt;br /&gt;//returns true if they are, otherwise false&lt;br /&gt;Equals = function(a,b)&lt;br /&gt;{&lt;br /&gt;  //Check if the arrays are undefined/null&lt;br /&gt;  if(!a || !b)&lt;br /&gt;    return false;&lt;br /&gt;&lt;br /&gt;  //first compare their lengths&lt;br /&gt;  if(a.length == b.length)&lt;br /&gt;  {&lt;br /&gt;    //go thru all the vars&lt;br /&gt;    for(var i = 0; i &lt; a.length;i++)&lt;br /&gt;    {&lt;br /&gt;      //if the var is an array, we need to make a recursive check&lt;br /&gt;      //otherwise we'll just compare the values&lt;br /&gt;      if(typeof a[i] == 'object') {&lt;br /&gt;        if(!Equals(a[i],b[i]))&lt;br /&gt;          return false;&lt;br /&gt;      }&lt;br /&gt;      else if(a[i] != b[i])&lt;br /&gt;        return false;&lt;br /&gt;    }&lt;br /&gt;    return true;&lt;br /&gt;  }&lt;br /&gt;  else return false;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;if(Equals(a,b)) { /* ... */ }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;ookay!&lt;br /&gt;&lt;br /&gt;You might notice that the usual JavaScript naming convention is that function names start with a small letter. I use capital letters just because I'm used to that from C# and it looks better to my eye.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115355933793647141?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115355933793647141/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115355933793647141' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115355933793647141'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115355933793647141'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/07/comparing-and-copying-arrays-in.html' title='Comparing and copying arrays in JavaScript is a pain'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115295306250609856</id><published>2006-07-15T11:44:00.000+03:00</published><updated>2006-07-18T06:19:48.203+03:00</updated><title type='text'>Object-oriented JavaScript</title><content type='html'>I'm working on a "World Clocks" widget for Opera 9. It's basically something which can display multiple clocks set in different timezones.&lt;br /&gt;&lt;br /&gt;As the widgets in Opera 9 are coded with HTML and the like, the actual funcionality is written in JavaScript. Therefore I was thinking about a way to implement the different clocks and thought about making it a class.&lt;br /&gt;&lt;br /&gt;Classes in JavaScript are a thing many don't know of, so I'll write an introduction to them, based on the Clock class I made.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;The idea&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;The idea is to make a Clock class... as we're going to have one or more of them, the time can be taken from a "central location", this time a JavaScript Date object.&lt;br /&gt;Because of this, the Clock itself will not store a time, it will just format the time based on it's settings.&lt;br /&gt;&lt;br /&gt;Things we're going to store in the clock for starters: Clock's name/id and the clock's offset from GMT +0. It should also have functions for returning the HTML-element for the clock and updating it's element in the document.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Let's begin!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Creating a class in JavaScript is actually a function definition:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function Clock(name,timeOffset) &lt;br /&gt;{&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now we need to add the variables for storing the name and the offset.&lt;br /&gt;To add member variables to the class, the following syntax is used:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function Clock(name,timeOffset)&lt;br /&gt;{&lt;br /&gt; this.name = name;&lt;br /&gt; this.offset = timeOffset;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The values required by the Clock function are set to the member variables.&lt;br /&gt;Adding functions to the class works in a very similar fashion:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;function Clock(name,timeOffset)&lt;br /&gt;{&lt;br /&gt; this.name = name;&lt;br /&gt; this.offset = timeOffset;&lt;br /&gt;&lt;br /&gt; this.Tick = function(time)&lt;br /&gt; {&lt;br /&gt;  var h = time.getUTCHours();&lt;br /&gt;  var m = time.getUTCMinutes();&lt;br /&gt;  var s = time.getUTCSeconds();&lt;br /&gt;  &lt;br /&gt;  if(m &lt; 10) m = '0'+m;&lt;br /&gt;  if(s &lt; 10) s = '0'+s;&lt;br /&gt;  &lt;br /&gt;  h = Number(h) + Number(this.offset);&lt;br /&gt;  if(h &gt; 23) h -= 24;&lt;br /&gt;  if(h &lt; 0) h += 24;&lt;br /&gt;  &lt;br /&gt;  var obj = document.getElementById(name+'_time');&lt;br /&gt;  obj.innerHTML = h+':'+m+':'+s;&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; this.GetElement = function()&lt;br /&gt; {&lt;br /&gt;  var base = document.createElement('div');&lt;br /&gt;  base.id = name;&lt;br /&gt;  base.className = 'clock';&lt;br /&gt;  &lt;br /&gt;  var label = document.createElement('h2');&lt;br /&gt;  label.id = name+'_label';&lt;br /&gt;  label.className = 'label';&lt;br /&gt;  label.innerHTML = name;&lt;br /&gt;  &lt;br /&gt;  base.appendChild(label);&lt;br /&gt;  &lt;br /&gt;  var time = document.createElement('span');&lt;br /&gt;  time.id = name+'_time';&lt;br /&gt;  time.className = 'time';&lt;br /&gt;  time.innerHTML = '00:00:00';&lt;br /&gt;  &lt;br /&gt;  base.appendChild(time);&lt;br /&gt;  &lt;br /&gt;  return base;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Firstly, there's the Tick function. It takes a JavaScript time object as it's parameter.&lt;br /&gt;From the time object we take three values: the UTC hour, UTC minutes and UTC seconds. Then we check whether the minutes or seconds are smaller than 10 and add a zero to the front to make them appear nicer in the formatting.&lt;br /&gt;&lt;br /&gt;As UTC equals GMT +0, we just add the GMT offset to the UTC hours to get the time in the desired timezone. Now, if the clock was 23:00 GMT+0 and we added there, say, 6 hours, the clock would obviously show something completely wrong... 29:00 isn't a proper time as you might know. That's why the next thing we do is check whether the time goes out of bounds and add or remove 24 hours for making it correct again.&lt;br /&gt;&lt;br /&gt;The the code just gets the element for the clock and sets it to show the time.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then the GetElement function..&lt;br /&gt;First, we create an empty div element to hold the clock. We give the clocks name for the div as it's ID and set it's CSS class name to 'clock'. Then we create a h2 element for displaying the clock's name. Again we set the id and CSS class name and also the innerHTML is changed to the clocks name. After this, we append the h2 element to the div we created first.&lt;br /&gt;Finally we create a span for displaying the actual time for the clock and add that too to the div. Finally we return the whole div object.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Finally...&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;Using this class would be simple as this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//create a new clock&lt;br /&gt;var myclock = new Clock('example',3); &lt;br /&gt;&lt;br /&gt;//add the clock's element to the document&lt;br /&gt;document.body.appendChild(myclock.GetElement());&lt;br /&gt;&lt;br /&gt;//Update the clock once with the current time&lt;br /&gt;myclock.Tick(new Date());&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So there we have the Clock class. There's a bunch of things which could be added, like storing a daylight savings time, so the clock would automatically stay in the proper time in case of DST. Also, the Tick function could check if the passed variable is actually a Date object or not and it could also allow the user to format the time in 12-hour format instead of 24-hour.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;In case you want to check out the widget I'm working on, &lt;a href="http://widgets.opera.com/widget/4648" target="_blank"&gt;you can download it from Opera Widgets&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Some intresting reading on JavaScript can be found at &lt;a href="http://www.crockford.com/javascript/javascript.html" target="_blank"&gt;"JavaScript: the worlds most misunderstood programming language"&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115295306250609856?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115295306250609856/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115295306250609856' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115295306250609856'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115295306250609856'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/07/object-oriented-javascript.html' title='Object-oriented JavaScript'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115268289155912069</id><published>2006-07-12T07:52:00.000+03:00</published><updated>2006-07-12T08:48:35.110+03:00</updated><title type='text'>Feed button generator - graphics with PHP and ImageMagick</title><content type='html'>On the other day while browsing, an idea struck me... You often see these "RSS Feed", "CSS 2.0" and other buttons in the style of my new RSS feed link. I thought it would be cool to try to make a PHP script which would generate these graphics!&lt;br /&gt;&lt;br /&gt;So I present you...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://iikeli.ath.cx:1337/projects/feedbutton/" target="_blank"&gt;&lt;h2&gt;The feed button generator!&lt;/h2&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The button generator uses PHP and ImageMagick. The interface uses JavaScript for the color picker and for quickly displaying the newly generated image without having the page to refresh or such. It's &lt;i&gt;Web 2.0&lt;/i&gt;, baby!&lt;br /&gt;&lt;br /&gt;ImageMagick is a quite advanced graphics toolkit which works from the console. There is also an interface for PHP, but as it requires a recompile of PHP, I didn't install it. I used exec() to use the imagick command line tools.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The image generation script itself is quite simple. It checks for $_GET variables which contain the options for the button, like the text on the left side and uses a default value for each if there's no user-defined value.&lt;br /&gt;&lt;br /&gt;Each of the GET variables used are ran through escapeshellcmd() to make sure the user can't try anything we don't want him to.&lt;br /&gt;&lt;br /&gt;The ImageMagick command used, however, is worth a better look:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;$cmd = IMAGICK_PATH.'convert -size '.$w.'x'.$h.' xc:black ';&lt;br /&gt;$cmd.= '-fill white -draw \'rectangle 1,1 '.($w-2).','.($h-2).'\' ';&lt;br /&gt;$cmd.= '-fill "#'.$lsbgcol.'" -draw \'rectangle 2,2 '.$vbarpos.','.($h-3).'\' ';&lt;br /&gt;$cmd.= '-fill "#'.$rsbgcol.'" -draw \'rectangle '.($vbarpos+2).',2 '.($w-3).','.($h-3).'\' ';&lt;br /&gt;$cmd.= '-font lucon.ttf -pointsize 10 -fill "#'.$lstcol.'" -draw "text 5,11 \''.$lstext.'\'" ';&lt;br /&gt;$cmd.= '-fill "#'.$rstcol.'" -draw "text '.($vbarpos+4).',11 \''.$rstext.'\'" ';&lt;br /&gt;$cmd.= $path.'/'.$tmpname;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;It probably looks quite complicated with all the inline variables. So let's also display a sample output for that.&lt;br /&gt;&lt;br /&gt;/usr/bin/convert -size 80x15 xc:black -fill white -draw 'rectangle 1,1 78,13' -fill "#FF6600" -draw 'rectangle 2,2 30,12' -fill "#898E79" -draw 'rectangle 32,2 77,12' -font lucon.ttf -pointsize 10 -fill "#FFFFFF" -draw "text 5,11 'RSS'" -fill "#FFFFFF" -draw "text 34,11 'Feed'" /wwwroot/projects/feedbutton/1152680468.gif&lt;br /&gt;&lt;br /&gt;And it might still look complicated, so let me explain it a bit.&lt;br /&gt;&lt;br /&gt;Starting with the IMAGICK_PATH.. it's the path to the ImageMagick binaries, in this case "/usr/bin/". The applications name is convert.&lt;br /&gt;&lt;br /&gt;the -size parameter is probably self explanatory. It sets the size of the canvas to 80x15. $w and $h contain the values for this.&lt;br /&gt;&lt;br /&gt;xc:black sets the background color of the canvas to black. You could use hexadecimal color values here too, like xc:FFFFFF.&lt;br /&gt;&lt;br /&gt;with -fill, you set the fill color for drawing and the text color for drawing text. As you can see from further, you can use hexadecimal values too but they have to be inside quotes.&lt;br /&gt;&lt;br /&gt;the -draw parameter draws all kinds of shapes. In this case, we're just drawing a bunch of rectangles and some text. &lt;br /&gt;Draw takes some parameters of it's own which go inside single quotes. The first parameter is the type of the shape to draw, for example, rectangle. When drawing rectangles, you also have to give it the &lt;i&gt;top left corner&lt;/i&gt; and the &lt;i&gt;width and the height&lt;/i&gt; of the rectangle.&lt;br /&gt;&lt;br /&gt;As we want to have the button to have a one pixel border, we set the top left corner of the rectangle at 1,1 and the width and height to 78,13. The rectangle's width and height are determined by width-2 and height-2 as seen in the code.&lt;br /&gt;&lt;br /&gt;After drawing the first rectangle, the fill color is switched to the color of the box on the left side. It's drawn in exactly the same fashion as the first one. However, this time we're using the position of the middle bar as the width.&lt;br /&gt;&lt;br /&gt;Next, the script draws the right side box. This time the starting position's x position is set to middle bar position + 2 to make the one pixel white bar appear in the middle, thus the name "middle bar". (In the code the variables name comes from "vertical bar position", it's before I figured out a better name for it)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;As you can see, drawing rectangles is easy. If you wanted to draw more rectangles, you would just add more -draw parameters and -fill's for changing colors.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now the only thing left to draw are the texts that appear in the button. This is done in a very similar way as the rectangle drawing.&lt;br /&gt;&lt;br /&gt;First, the font is defined with -font parameter. lucon.ttf was stolen from my windows' font directory and moved to the server... it's "Lucida Console".&lt;br /&gt;&lt;br /&gt;-pointsize defines the size of the font.&lt;br /&gt;&lt;br /&gt;To draw the text, the rectangle parameter is just switched to text. The two numbers are the top left corner of the position of the text and after that comes the text to draw.&lt;br /&gt;&lt;br /&gt;Drawing more text is yet again done by adding another draw parameter.&lt;br /&gt;&lt;br /&gt;Finally, our newly created button is saved with a temporary file name, which is generated by PHP using date(). The $path variable holds the path of the script so it's saved to the correct directory. &lt;br /&gt;The path can be found by calling substr($_SERVER['SCRIPT_FILENAME'],0,strrpos($_SERVER['SCRIPT_FILENAME'],'/'));&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After saving the image to disk, the image.php script calls header('Content-Type: image/gif') and include()'s the temporary file. After this the file is unlink()'d as it's not needed anymore.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The JavaScript color picker is &lt;a href="http://www.softcomplex.com/products/tigra_color_picker/demo1.html" target="_blank"&gt;Tigra Color Picker&lt;/a&gt;. Other than that, the JavaScript in the page is quite simple, as it only changes the src attribute of the img element which displays the image generated. The page should also work in case JavaScript is unavailable for some reason. In that case, the user gets redirected to the image.php script which will display a graphic with the users' configuration.&lt;br /&gt;&lt;br /&gt;Note that you'll have to remove any # characters from an URL if you're using it as an image's src attribute... otherwise you'll end up in trouble and get a very random looking error and random behavior. At least in my case.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can find more info on ImageMagic, including installation info from &lt;a href="http://www.imagemagick.org/script/index.php" target="_blank"&gt;their homepage.&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.cit.gu.edu.au/~anthony/graphics/imagick6/" target="_blank"&gt;Here are many examples of using ImageMagic&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115268289155912069?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115268289155912069/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115268289155912069' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115268289155912069'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115268289155912069'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/07/feed-button-generator-graphics-with.html' title='Feed button generator - graphics with PHP and ImageMagick'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115204185254624803</id><published>2006-07-04T21:50:00.000+03:00</published><updated>2006-07-04T22:37:32.636+03:00</updated><title type='text'>Traffic simulation</title><content type='html'>Since I've been very much in trouble because of traffic jams, I've been thinking about how traffic and such is actually simulated in games and applications.&lt;br /&gt;&lt;br /&gt;Basically you need to have roads and vehicles. You also want intersections, otherwise it might be a quite useless sim :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Roads are organized in stretches: a certain speed limit, a certain length and certain amount of lanes. For the sim let's say each stretch also has a starting point and an ending point, which can be connected to other stretches of road or intersections and such.&lt;br /&gt;&lt;br /&gt;A lane on the other hand is a piece of a road which has a direction, coming or going, which depends on the point of view but for the sake of simplicity let's just define that "going" means moving from the start point of a stretch to the end point and "coming" the other way around.&lt;br /&gt;&lt;br /&gt;Cars drive on lanes. They drive at a certain speed. They can also switch lanes if there are more lanes going to the same direction, so they need to be aware of other lanes and other vehicles around them. They also need to have a size and a position on the lane, so other vehicles can avoid them and such. This should also be used to determine whether a lane is full when a car is in an intersection trying to enter a lane.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There is also another way of thinking the road-lane thing... you could have "just" lanes. They would then hold the begin and end point links to other lanes, have a certain length etc.&lt;br /&gt;I haven't yet determined which one is a better approach, the road-lane or just lanes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So far code-wise this means something like the following:&lt;br /&gt;A Road class which holds Lane objects, has a speed limit and a length. Also a begin and an end points, which can be references to other Road objects&lt;br /&gt;&lt;br /&gt;A Lane class, has a reference to the parent road, a direction (coming/going) and a list of Cars on the lane. They should contain methods for cars entering and leaving the lane.&lt;br /&gt;&lt;br /&gt;A Car class which has a speed, size and position in the current lane. It should also hold a variable which marks where it wants to turn in the next intersection so it can navigate to the proper lane and turn in the intersection.&lt;br /&gt;Cars need methods for scanning for other cars, moving, stopping, changing lanes, maybe more.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The whole deal of moving around the lanes could also be left just for the Cars. The lanes wouldn't know about the cars on them. The cars would navigate how they best see to fit and only use the Lanes to help navigate around. This is another thing I haven't yet tried, as I'm still working on implementing the roads, lanes, cars and movement and such. &lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Intersections. Let's keep it simple for now at least. When a car arrives at an intersection, it must pick the lane where it can continue to the direction it wants to go. Therefore the lanes in intersections need to have target lanes in the road objects which are linked to the intersection. Also, cars should obey some kind of traffic regulations like letting the cars coming from right go first. So to do that the cars will have to be yet again able to see if there are any cars coming to the intersection from the other roads. Other things to note are, of course, traffic lights. Red or green for keeping things simple again. If the light is red, car stops. Green, go!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I made some classes for working some of these things out. I might post them later if I get them doing anything intresting.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.traffic-simulation.de/" target="_blank"&gt;Here's a small traffic simulator in Java&lt;/a&gt;. It may seem to get stuck when you adjust the sliders but just wait a moment and it'll continue.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115204185254624803?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115204185254624803/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115204185254624803' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115204185254624803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115204185254624803'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/07/traffic-simulation.html' title='Traffic simulation'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115153892322868241</id><published>2006-06-29T02:33:00.000+03:00</published><updated>2006-06-29T02:55:23.306+03:00</updated><title type='text'>Flashy</title><content type='html'>I've been tinkering with Flash 8 a bit. I made &lt;a href="http://iikeli.ath.cx:1337/tank.swf" target="_blank"&gt;a tank&lt;/a&gt; which moves around with the arrow keys and the turret follows the mouse cursor. Yes, I know the turret rotates wrong if you turn the tank.&lt;br /&gt;&lt;br /&gt;ActionScript seems like a rather easy to learn language. I doubt I will start making anything "serious" with Flash, but I might have to code some ActionScript for a project soon so I thought I'd practice.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Regarding the game project, I've been pretty stuck. I've been browsing through the code but haven't written any. There's just something... wrong... in it. I think it's the batching thing. It's not as flexible as I'd want it to be, at least not at the moment. I think I'll have to make the changes to it &lt;a href="http://zeeohemgee.blogspot.com/2006/06/ideas-for-pipeline-and-gui.html" target="_blank"&gt;which I was talking about here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;And I still hate the text drawing method. It's just so &lt;i&gt;crap&lt;/i&gt; compared to how it works in winforms.&lt;br /&gt;&lt;br /&gt;How it works now is that you pass a size, font, text and colors to a CustomText Control, which in turn creates a texture with the text and coloring and you can then place the CustomText control wherever you want to show the text at... the problem is that the text quality is so horrible. I want crisp fonts! &lt;br /&gt;Adjusting the size and stuff takes quite much effort now.. it can be done this way too but meh... it's troublesome.&lt;br /&gt;&lt;br /&gt;I know you could probably do something like bitmap fonts, but I find it clumsy.&lt;br /&gt;Another method would be saving the whole block of text into a pre-made texture and using that, which would work fine for static text, but what if you want to make a list of... let's say, maps. That list can obviously change so you'd need to make a texture for the map text... not good.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Well in any case, I'll have to do something about the rendering. Also the z order stuff is troubling... I added z order sorting to the pipeline, but that doesn't work very well as things with the same z order may get a different rendering order which then may cause flickering.&lt;br /&gt;&lt;br /&gt;This is one of the things what is wrong with the rendering. Previously I could just stuff things to it and render away and they would appear in correct order because the quad vertices were ordered properly. Now if I separated the pipelinebuffers so that the maps would have it's own and the objects and the GUI and they could each be rendered separately.. then I'd get rid of the z order prob too. First render the map, then the objects and then the gui. Problem solved. Of course there's also the issue of using the vertices Z position and the z buffer but that would make them appear wrong because I'm not using ortogonal projection.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Whatever. Maybe I'll get something done when I get bored with Sim City =)&lt;br /&gt;And here's the link for today..&lt;br /&gt;&lt;a href="http://www.c-unit.com/tutorials/mdirectx/" target="_blank"&gt;Here&lt;/a&gt; are some good MDX tutorials, including a pretty extensive ones about GUI.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115153892322868241?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115153892322868241/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115153892322868241' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115153892322868241'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115153892322868241'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/flashy.html' title='Flashy'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115143103418319208</id><published>2006-06-27T21:00:00.000+03:00</published><updated>2006-06-27T21:01:56.826+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>C# snippets - create a "transparent" click-through window</title><content type='html'>I ran into this at the C# channel today.. One guy wanted to create a window, which would be on top of another app and if you clicked that window, the window would not get activated and the event would be sent to the app below it instead.&lt;br /&gt;&lt;br /&gt;Here's the code you need to accomplish this:&lt;br /&gt;&lt;br /&gt;These two WinAPI functions are required&lt;br /&gt;&lt;br /&gt;[DllImport("user32.dll")]&lt;br /&gt;static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);&lt;br /&gt;&lt;br /&gt;[DllImport("user32.dll")]&lt;br /&gt;static extern long GetWindowLong(IntPtr hWnd, int nIndex);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Then the actual form/window is made "transparent" with this call (this.Handle being the forms' handle)&lt;br /&gt;&lt;br /&gt;SetWindowLong(this.Handle,-20,GetWindowLong(this.Handle,-20) | 0x00000020)&lt;br /&gt;&lt;br /&gt;The values (-20, -20 and 0x00000020) are respectively the following from winuser.h: GWL_EXSTYLE, WS_EXSTYLE and WS_EX_TRANSPARENT&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And as a side note, I did end up installing SC4... and what have I been doing?... Well, playing it. Not coding like I should be! :]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115143103418319208?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115143103418319208/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115143103418319208' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115143103418319208'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115143103418319208'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/c-snippets-create-transparent-click.html' title='C# snippets - create a &quot;transparent&quot; click-through window'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115088814770921849</id><published>2006-06-21T14:06:00.000+03:00</published><updated>2006-06-21T14:09:07.763+03:00</updated><title type='text'>Opera 9 has reached final</title><content type='html'>The Opera browser has now reached version 9 which adds lots of fixes and new features... Widgets, BitTorrent support, SVG vector graphic support and many small things.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.opera.com" target="_blank"&gt;Opera can be downloaded from here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;When installing you may want to note that if you're installing on top of your old Opera installation and you are using a custom language, it may remove all text in any buttons and such, so make backups of your bookmarks and make a completely new install.&lt;br /&gt;&lt;br /&gt;Also, if you can't find things like Widgets in the menu, Content blocking in the right click menu or such, you need to go to preferences, toolbars and choose Opera standard from "Menu setup"&lt;br /&gt;&lt;br /&gt;And here's some links about why choose Opera:&lt;br /&gt;&lt;a href="http://virtuelvis.com/archives/2004/11/opera-over-firefox" target="_blank"&gt;Why I Prefer Opera over Firefox?&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.gungfu.de/facts/archives/2004/11/22/why-i-love-opera/" target="_blank"&gt;Why I Love Opera&lt;/a&gt;&lt;br /&gt;&lt;a href="http://sebastienguillon.com/journal/2005/09/10-reasons-to-choose-opera" target="_blank"&gt;10 reasons to choose Opera&lt;/a&gt;&lt;br /&gt;&lt;a href="http://operalover.tntluoma.com/day_1_general_preferences" target="_blank"&gt;30 days to becoming an Opera 8 lover&lt;/a&gt;&lt;br /&gt;&lt;a href="http://mywebpages.comcast.net/SupportCD/FirefoxMyths.html" target="_blank"&gt;Firefox myths&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note that this one is not completely serious&lt;br /&gt;&lt;a href="http://www.slyerfox.com/" target="_blank"&gt;Slyerfox&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;small&gt;Also, why do I keep typoing widge&lt;i&gt;t&lt;/i&gt;s as widge&lt;i&gt;r&lt;/i&gt;s?&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115088814770921849?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115088814770921849/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115088814770921849' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115088814770921849'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115088814770921849'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/opera-9-has-reached-final.html' title='Opera 9 has reached final'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115088513461089477</id><published>2006-06-21T13:15:00.000+03:00</published><updated>2006-06-21T13:18:54.610+03:00</updated><title type='text'>Layout changes ahoy</title><content type='html'>I think I'm finally going to dump this ready-made layout this blog is using. I've made some changes as you might see (like the image in the header bar), but still it's a generic one.&lt;br /&gt;&lt;br /&gt;I was thinking about something like &lt;a href="http://iikeli.ath.cx:1337/" target="_blank"&gt;the frontpage on my home servers site&lt;/a&gt;... &lt;a href="http://iikeli.ath.cx:1337/blog/index.html" target="_blank"&gt;Here's some experiments&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Maybe even have it published there so I can use PHP/ASP.NET/whatever I want.&lt;br /&gt;&lt;br /&gt;I will probably experiment with that when I have all the CSS stuff written for it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115088513461089477?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115088513461089477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115088513461089477' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115088513461089477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115088513461089477'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/layout-changes-ahoy.html' title='Layout changes ahoy'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115082043867646513</id><published>2006-06-20T19:18:00.000+03:00</published><updated>2006-06-20T19:20:38.883+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Ideas for the Pipeline and GUI</title><content type='html'>Here are some drafts about things I'm thinking about changing in the batching class, RenderPipeline, I discussed earlier.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Move the Work() method into a &lt;i&gt;separate&lt;/i&gt; class. Have this class hold PipelineBuffer-objects.&lt;br /&gt;&lt;br /&gt;This way you could have very precise control over what to render, in what order, and when. The workerclasses could have a z-order in themselves or a container class like a game object manager or a GUI manager could contain one and render it if needed etc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The pipeline would be modified to maybe contain references to these classes. By doing this, the PipelineBuffer could also be abstracted more, for example, to allow a MeshPipelineBuffer and a QuadPipelineBuffer. Though they could probably be more abstracted even the way they are now, but anyway.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Anyway with this method you could have more control over what's rendered, what buffer is associated with what object/objectgroup etc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also for the GUI, I was thinking about implementing some kind of a manager as you might've noticed above. The manager would handle positioning the controls and such.&lt;br /&gt;As the screen is moved around, the GUI has to stay in one place obviously.&lt;br /&gt;&lt;br /&gt;The GUIManager class could itself be a generic one, which could be inherited from to allow for different handling of input. You could probably also have multiple instances of it, so you could "group" different gui elements. &lt;br /&gt;For example, a "game UI" which would contain the money amount, terrain details and such, and an "Object details UI" which would contain some boxes for showing details on a unit or a structure.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And regarding UI also, &lt;a href="http://download.microsoft.com/download/1/8/2/182200e0-cf87-47d6-87a7-32cb36bbfa42/Tutorial09.wmv" target="_blank"&gt;over here&lt;/a&gt; is a webcast from Microsoft's site about the input and GUI in a game called Rocket Commander. &lt;a href="http://msdn.microsoft.com/coding4fun/gamedevelopment/rocketcmd/default.aspx" target="_blank"&gt;The rest can be found here&lt;/a&gt;, quite much intresting stuff in them and also the whole game sourcecode is available too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115082043867646513?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115082043867646513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115082043867646513' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115082043867646513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115082043867646513'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/ideas-for-pipeline-and-gui.html' title='Ideas for the Pipeline and GUI'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115080992327044933</id><published>2006-06-20T16:21:00.000+03:00</published><updated>2006-06-20T16:25:23.343+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Finding the location of a point in a certain Z depth</title><content type='html'>I've been trying to solve a problem for my GUI code...&lt;br /&gt;&lt;br /&gt;If I unproject certain coordinates to the 3D space, I get a 3D Vector. Now, how to find out what that point would be in, let's say -5 Z instead of 0 Z?&lt;br /&gt;&lt;br /&gt;I was kind of lost for a while about how the point could be found, but now I've finally found an answer!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;//Let's say we want point 100 100&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: teal;"&gt;Vector3&lt;/span&gt; point = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Vector3&lt;/span&gt;(100, 100, 0);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;//Create near and far vectors&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: teal;"&gt;Vector3&lt;/span&gt; near = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Vector3&lt;/span&gt;(point.X, point.Y, 0);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: teal;"&gt;Vector3&lt;/span&gt; far = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Vector3&lt;/span&gt;(point.X, point.Y, 1);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;//Unproject them&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;near.Unproject(device.Viewport, device.Transform.Projection,&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; device.Transform.View, device.Transform.World);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;far.Unproject(device.Viewport, device.Transform.Projection,&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; device.Transform.View, device.Transform.World);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;//Create a plane at the z-depth (-5) we want to know the position&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: teal;"&gt;Plane&lt;/span&gt; zplane = &lt;span style="color: teal;"&gt;Plane&lt;/span&gt;.FromPointNormal(&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Vector3&lt;/span&gt;(0, 0, -5), &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Vector3&lt;/span&gt;(0, 0, 1));&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&amp;nbsp;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;//Intersect the line going from near point to far &lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: green;"&gt;//to get the result&lt;/span&gt;&lt;/p&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: teal;"&gt;Vector3&lt;/span&gt; resultPoint = &lt;span style="color: teal;"&gt;Plane&lt;/span&gt;.IntersectLine(zplane, near, far);&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The result obviously depends on the viewport, projection and such of your device.&lt;br /&gt;&lt;br /&gt;Ah well, now I can finally start thinking about the GUI placement.&lt;br /&gt;&lt;br /&gt;Getting the GUI in some kind of shape would allow me to do lots of new things, like unit detail sheets, building new units (which &lt;i&gt;was&lt;/i&gt; in with a very crap looking GUI), Attacking etc. so it's pretty vital to get it working properly!&lt;br /&gt;&lt;br /&gt;And for the sake of mentioning other things, I've recently felt like reinstalling Sim City 4... doing that might be dangerous since I could forget anything about coding and just build a better city for my sims to live in... :]&lt;br /&gt;&lt;br /&gt;It also looks like I might actually get something meaningful to do for this summer... I visited the company I do freelance-coding for yesterday and we had some talks about starting working on a Flash-project for a client. Would take the rest of the summer to work on that, and I'd get paid too, unlike when coding my own things ;)... Also, as I don't know Flash very well, I could also learn a bit of that though I will be mainly working on the ActionScript side of things.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115080992327044933?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115080992327044933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115080992327044933' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115080992327044933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115080992327044933'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/finding-location-of-point-in-certain-z.html' title='Finding the location of a point in a certain Z depth'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115065421954345143</id><published>2006-06-18T21:07:00.000+03:00</published><updated>2006-06-18T21:10:19.666+03:00</updated><title type='text'>Hacking^2</title><content type='html'>This time, I'll present you a documentary of my ventures into the magical world of Linux, the superior operating system! (note the sarcastic tone)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So I wanted to install mod_mono to my server machine so I can run ASP.NET applications with Apache.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;One:&lt;/b&gt;&lt;br /&gt;I had to upgrade the kernel&lt;br /&gt;&lt;br /&gt;First I tried to build it from the source, which didn't work however. Thinking how to get it back running, I decided to see if the Ubuntu discs I have contain a rescue mode (the box itself is using Debian).&lt;br /&gt;&lt;br /&gt;Well they did but... the rescue mode somehow managed to garble the console so text editors and such wouldn't work!&lt;br /&gt;&lt;br /&gt;Then trying to figure out how to get them running properly... well, I finally thought about trying "rescue debian-installer/framebuffer=false" boot option, which luckily fixed the issue and I got into a proper console, finally.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So I did the rescuing and stuff (I won't go into details, I'll just say it wasn't very easy). I later found out that I was supposed to compile something called cramfs into the kernel. Well, intrestingly enough the kernel menuconfig utility which is used to configure it before compiling didn't even have an option for it! I would have had to manually edit the config file (which isn't really a very big task, but anyway)...&lt;br /&gt;&lt;br /&gt;I gave up with the idea of compiling the kernel and just downloaded a pre-built one from Debian packages. Thank god for that.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;two:&lt;/b&gt;&lt;br /&gt;I had to install Mono&lt;br /&gt;&lt;br /&gt;Mono wanted me to install a new version of libc6. Well, okay, I thought. Let's just switch to the unstable apt-get sources.&lt;br /&gt;&lt;br /&gt;Now, then... the libc6 install wanted to &lt;i&gt;remove the kernel&lt;/i&gt;. Yes, &lt;i&gt;remove the &lt;b&gt;kernel&lt;/b&gt;&lt;/i&gt;. Uhhh right! Let's remove it!... &lt;b&gt;not!&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Okay, time to go ask some people who might actually know something about this unlike I do! &lt;br /&gt;[Quakenet] /j #debian&lt;br /&gt;&lt;br /&gt;The wise man (thanks cortana) of the channel told me about a thing called backports, which might help me.. okay. I yet again change my apt sources.list to include backports and try to install the required things from backports... nothing again. Still running against the wall. I had also the pleasure of meeting Fangorn, the channel jester who absolutely loved me, because my nick (zomg) somehow offended him and "publicly insults religions" and I had also called him a faggot (which I absolutely did not) and whatnot. If you're ever reading this, Fangorn, I love you too!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Continuing my journey, I decided to try apt-get install'ing both libc6 &lt;i&gt;and&lt;/i&gt; the kernel. Well well! It told me that kernel is already at the latest version and &lt;i&gt;proceeded with the libc6 installation!&lt;/i&gt;. "zomg WINSSS - FATALITY!", I thought... but I was happy too soon.&lt;br /&gt;&lt;br /&gt;Then began the fight to install libapache-mod-mono. It would require a specific version of apache-mono-server... which was, however, not even available from any of Debian's package sources! Oh man...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Trying to fix the thing again from backports with no success. Trying to compile it from the source code, which worked but I never got it working with apache...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I thought Ubuntu also had mod_mono, I had seen something about ubuntu and mono.&lt;br /&gt;Looking up the ubuntu package page in Opera, I search their packages... and yay, they happen to have them!&lt;br /&gt;&lt;br /&gt;Now, adding the ubuntu sources to my sources.list and updating the cache... apt-get'ing the files... everything worked smoothly. I got the things running, finally!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I wonder if my distro is called Debuntu now...&lt;br /&gt;&lt;br /&gt;and finally, maybe some fun! Youtube-links, yay&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=RSizsFSOd84&amp;search=Seebach" target="_blank"&gt;"Apache"&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=sZ4Bt-2zJKo&amp;search=Seebach" target="_blank"&gt;"Apache" + Painkiller&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115065421954345143?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115065421954345143/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115065421954345143' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115065421954345143'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115065421954345143'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/hacking2.html' title='Hacking^2'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115036436808527794</id><published>2006-06-15T12:31:00.000+03:00</published><updated>2006-06-15T12:40:02.940+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Input management</title><content type='html'>I was playing with an idea about how to manage different kinds of "input" (and also output) in a turn-based game. This stuff could probably be applied to non-turn-based games too.&lt;br /&gt;&lt;br /&gt;For example:&lt;br /&gt;-input from the local player through keyboard and mouse&lt;br /&gt;-input from the AI "player"&lt;br /&gt;-input from a remote player through a network connection&lt;br /&gt;&lt;br /&gt;Now, the game engine has methods to do things in the game, like moving units around the screen and such. Now the thing is, how to express this information to the different types of "players" in the game.&lt;br /&gt;&lt;br /&gt;A local player needs to see things on his screen:&lt;br /&gt;-messages, menus, animation&lt;br /&gt;&lt;br /&gt;AI needs to access the "raw" data&lt;br /&gt;&lt;br /&gt;A remote player needs to get the data through the network:&lt;br /&gt;-The data from the local machine must be sent through the network&lt;br /&gt;-The game running on the remote host must parse the data and display it to the user&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So the idea I'm playing with now is that the engine itself does not know what kind of a player it's sending the data to. The engine would just have a bunch of messages and states like...&lt;br /&gt;-Waiting for input from player&lt;br /&gt;-Waiting for confirmation of action&lt;br /&gt;-Turn begins&lt;br /&gt;-Unit selected&lt;br /&gt;-Unit moving&lt;br /&gt;-Unit reached destination&lt;br /&gt;&lt;br /&gt;etc.&lt;br /&gt;&lt;br /&gt;The engine would forward these kinds of messages to a IO handler class, which would implement some interface the engine uses. The IO handler class itself would then decide the course of action, depending if it's a "RemotePlayerIO" or "AIIO" or whatever.&lt;br /&gt;&lt;br /&gt;For example, a LocalPlayerIO gets a message "Unit destroyed"... it plays an animation of a unit blowing up in the game and plays a sound, as where an ArtificialIntelligenceIO would do something like removing the unit from the DB or something.&lt;br /&gt;&lt;br /&gt;The IO handler class would also be have to be able to query things from the engine, like "give me this unit's details" or "is there anyone in this tile?" and things like that.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Basically it would act as a proxy between the engine and the user(s).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Oh well. This is another of my gazillion or so ideas about all kinds of stuff.&lt;br /&gt;There are more important matters than this, like making the GUI code (finally)... but for some reason I keep avoiding it and doing other stuff. Getting the GUI done would allow for some more progress, instead of adding "nice touches" or random things here and there.&lt;br /&gt;&lt;br /&gt;It's summer holidays and what have I been doing? Sitting in front of the computer, writing code... nothing better to do I guess.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115036436808527794?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115036436808527794/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115036436808527794' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115036436808527794'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115036436808527794'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/input-management.html' title='Input management'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115034857523577187</id><published>2006-06-13T04:31:00.000+03:00</published><updated>2006-06-15T08:16:15.330+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Batching code</title><content type='html'>Since it seems there's not much resources around regarding batching quads or such, and my batching code seems to be working fine, I thought I'd post it. Maybe someone can learn something from it (or hopefully someone will point out obvious mistakes from it so I can learn something, *cough* *cough*)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Note:&lt;/i&gt;&lt;br /&gt;It's not ready&lt;br /&gt;It probably does not work with other things than quads&lt;br /&gt;It probably has bugs&lt;br /&gt;It probably could be done better&lt;br /&gt;&lt;br /&gt;&lt;i&gt;The GEngine-class:&lt;/i&gt;&lt;br /&gt;DeviceAvailable is true if the device can be rendered to&lt;br /&gt;GfxDevice is the actual DirectX.Device&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://students.osao.fi/~b3haja01/batching.html" target="_blank"&gt;Here's the code&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;I tried to add some useful comments, but if something is unclear, ask away.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;Basic usage:&lt;/i&gt;&lt;br /&gt;Create some quads (which implement IPipelineable)&lt;br /&gt;Use RenderPipeline.Add(foo) to add each of them into the pipeline&lt;br /&gt;In the render loop, call RenderPipeline.Work() and RenderPipeline.Render()&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also, here's my Quad class. Probably useful for seeing the IPipelineable implementation&lt;br /&gt;&lt;a href="http://students.osao.fi/~b3haja01/quad.html" target="_blank"&gt;Quad code&lt;/a&gt;&lt;br /&gt;&lt;i&gt;Note:&lt;/i&gt;&lt;br /&gt;This is probably even more WIP than the batching code&lt;br /&gt;Contains old, pre-batching code because I'm lazy&lt;br /&gt;Doesn't contain (much) comments, also because I'm lazy&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115034857523577187?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115034857523577187/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115034857523577187' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115034857523577187'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115034857523577187'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/batching-code.html' title='Batching code'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115008465170533450</id><published>2006-06-12T06:55:00.000+03:00</published><updated>2006-06-12T07:08:55.160+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>User Interface</title><content type='html'>I'm reworking the classes I used for creating some simple GUI elements. The old classes I had were a bit bad I might say... not very simple to use as I'd like.&lt;br /&gt;&lt;br /&gt;I'm currently working on a bit similar model as System.Windows.Forms.Control uses. &lt;br /&gt;&lt;br /&gt;I have a "base" class called Control. It's basically a class which holds 1-9 Quad-objects.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;div style="font-family: Courier New; font-size: 10pt; color: black; background: white;"&gt;&lt;br /&gt;&lt;p style="margin: 0px;"&gt;&lt;span style="color: teal;"&gt;Control&lt;/span&gt; c = &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;Control&lt;/span&gt;(&lt;span style="color: teal;"&gt;Vector3&lt;/span&gt;.Empty, &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;SizeF&lt;/span&gt;(5, 10));&lt;/p&gt;&lt;p style="margin: 0px;"&gt;c.SetBorders(0.1f);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;c.SetTexture(&lt;span style="color: teal;"&gt;TextureManager&lt;/span&gt;.GetTextureData(&lt;span style="color: maroon;"&gt;"white"&lt;/span&gt;));&lt;/p&gt;&lt;p style="margin: 0px;"&gt;c.SetBackgroundColor(&lt;span style="color: teal;"&gt;Color&lt;/span&gt;.Brown);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;c.SetBorderColor(&lt;span style="color: teal;"&gt;Color&lt;/span&gt;.Red);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;c.HookMouse();&lt;/p&gt;&lt;p style="margin: 0px;"&gt;c.MouseOver += &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;EventHandler&lt;/span&gt;(c_MouseOver);&lt;/p&gt;&lt;p style="margin: 0px;"&gt;c.MouseOut += &lt;span style="color: blue;"&gt;new&lt;/span&gt; &lt;span style="color: teal;"&gt;EventHandler&lt;/span&gt;(c_MouseOut);&lt;/p&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;Okay and now the CopySourceAsHTML2005 plugin has been tested too.&lt;br /&gt;&lt;br /&gt;So that's how the Control works. I also made a quick wrapper around the mouse events in a WinForms Control. The HookMouse() command hooks mouse events from the MouseManager and allows for functionality like MouseOver and MouseOut.&lt;br /&gt;&lt;br /&gt;The Control initially holds a single Quad. When calling SetBorders, 8 more are added (top corners, top, left side, right side, bottom corners and bottom) which hold the actual border data. The whole block can only use a single texture, but I'm going to add UV-coordinate support and maybe completely different textures if I feel I'm going to use that.&lt;br /&gt;&lt;br /&gt;The color methods are simple: They just set a Material with the color given as Emissive light. Works wonders! If you use a white texture like in the example code, the color shows up, not as white, but as pure red if you set it to red. Result will obviously be different if you set a texture which is not white, but then you can use the functions to create different tones or such.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I'm going to add support for adding child controls, and maybe for dragging and dropping the controls to other places and such.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I also need to add something to allow a Control to smoothly slide from the side to the middle of the screen or something like that. Transitions, or whatever they should be called. They could probably just be a bunch of Vector3's which define the start location and the result location... maybe something fancy, like a rotation. &lt;br /&gt;&lt;br /&gt;Adding rotations would need matrixes though.. well, not necessarily, but I'm not going to work positioning all the different vertices by hand when they're turned or such! Maybe later.&lt;br /&gt;Using a matrix translation for a menu transition or something would cause very little effect on performance. It would just require one another DrawIndexedPrimitives call anyway, as the whole menu could be batched using the same matrix, and the functionality for sorting quads into proper buffers is already in the RenderPipeline, I just need to add detections for matrixes there or such.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Gah. Maybe it would be time to go sleep. 7 AM... so it's getting kind of late.. or early, depending on how you like to think. ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115008465170533450?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115008465170533450/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115008465170533450' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115008465170533450'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115008465170533450'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/user-interface.html' title='User Interface'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-115004097094546593</id><published>2006-06-11T18:35:00.000+03:00</published><updated>2006-06-11T18:51:00.440+03:00</updated><title type='text'>How to get more debug data from DirectX?</title><content type='html'>I thought I'd write up something on getting more details on debug stuff from DirectX with managed languages as there's not much stuff up about that.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Tired of the "InvalidCallException" or "InvalidDataException" or whatever comes up in your app, with no data on what might be the cause? &lt;br /&gt;&lt;br /&gt;Well, for the users of Visual Studio Express Edition line, tough luck. Unmanaged debugging is only in "proper" Visual Studio's.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Okay here we go!&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step 1:&lt;/b&gt;&lt;br /&gt;Go to your projects properties by right clicking it in the solution explorer and choosing properties. On the debug page, tick "Enable unmanaged code debugging"&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step 2:&lt;/b&gt;&lt;br /&gt;Go to control panel and from there, DirectX. On the Direct3D tab, crank "Debug Output Level" to max, tick "Use Debug version of Direct3D" and "Break on D3D Error"&lt;br /&gt;Then go to Managed tab and go to Microsoft.DirectX and right click on the assembly name/number and choose "Switch to debug version". Do the same for Microsoft.DirectX.Direct3D&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Step 3:&lt;/b&gt;&lt;br /&gt;Start debugging your app. You should see a tab called "Output" in the debugger. If not, go to View menu in Visual Studio and select Output.&lt;br /&gt;The Output tab will contain the messages your app receives from the DirectX debugger.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;This was quite helpful for me when I tried to figure out what was wrong with my rendering, as the map editor just kept on crashing without giving me any clues on what was going wrong. In the end, it was something as simple as missing device.VertexFormat = something definition. &lt;br /&gt;The Direct3D error I got wasn't very helpful either, but after a bit of googling with it, I found an answer. More than I could ever find with "InvalidCallException" which is just waaaay too generic.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Seems the D3D debug also displays small tidbits like redundant state changes.&lt;br /&gt;I mean, device.RenderState changes. If you are using a Pure device, they aren't filtered out and will probably result in decreased performance.&lt;br /&gt;&lt;br /&gt;Another thing it seems to report is if a static buffer is locked more than twice in one frame, which is something which will cause a major performance hit if it's done often.&lt;br /&gt;&lt;br /&gt;Maybe others too.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-115004097094546593?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/115004097094546593/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=115004097094546593' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115004097094546593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/115004097094546593'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/how-to-get-more-debug-data-from.html' title='How to get more debug data from DirectX?'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114993875094431663</id><published>2006-06-10T11:45:00.000+03:00</published><updated>2006-06-11T16:17:50.856+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Implementing batching</title><content type='html'>H'Ok, so here's the earth... no wait, this is not &lt;a href="http://albinoblacksheep.com/flash/end.php" target="_blank"&gt;the end of the world&lt;/a&gt;...&lt;br /&gt;&lt;br /&gt;So. I got the FPS issues fixed for now at least. I implemented something I call the "Pipeline". I like fancy names for simple things! Makes them sound... more complicated.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It's basically a bunch of dynamically created VertexBuffers and sorting algorithms.&lt;br /&gt;&lt;br /&gt;To begin with, I changed my quad rendering code to use TriangeLists instead of TriangleFans to deal with the texture problem. I also added an IndexBuffer. That didn't affect the FPS (yet) as I was still doing waaay too many DrawIndexedPrimitives calls.&lt;br /&gt;&lt;br /&gt;Well, okay. As I had mentioned earlier, I had succesfully batched vertices in the tile map and got a big FPS boost. Now as I had some code to generate a VertexBuffer and IndexBuffer with TriangleList-style rendering, I could batch them and the textures would appear correctly too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So the batching worked wonderfully. There's a few things to mention though:&lt;br /&gt;If I wanted to use lights for a quad, it would have to be separated from the batch (I use lights to dim tiles to highlight the area a unit can move to)&lt;br /&gt;If I wanted to use a different texture, it would again have to be separated from the batch (except if using a texturemap and changing vertex U and V values)&lt;br /&gt;&lt;br /&gt;So to cope with those, I create the Pipeline-class.&lt;br /&gt;&lt;br /&gt;The basic principle of the Pipeline goes something like this:&lt;br /&gt;-Create new quad(s)&lt;br /&gt;-Add quads to the pipeline&lt;br /&gt;-Have the pipeline process the quads&lt;br /&gt;-Now you can render them using the pipeline&lt;br /&gt;&lt;br /&gt;Now the magic of the pipeline is done in the processing part.&lt;br /&gt;&lt;br /&gt;When adding quads to the pipeline, they first go into a list.&lt;br /&gt;&lt;br /&gt;The Pipeline has a method which processes the quads added:&lt;br /&gt;-Loop though "free" quads&lt;br /&gt;-Check if there's a PipelineBuffer with similar features as the quad&lt;br /&gt; -If we found a buffer, add the object to it&lt;br /&gt; -If not, create a new buffer with the quads properties&lt;br /&gt;-Clear free quad list as they should be assigned to a buffer now&lt;br /&gt;&lt;br /&gt;Free quads are ones which aren't yet assigned to any PipelineBuffer&lt;br /&gt;&lt;br /&gt;A PipelineBuffer is an object which holds quads. It can generate a VertexBuffer based on the quads and an IndexBuffer. It also contains details of the lights used, the material used and the texture used, so quads which can be batched together can be sorted from the free list and added to the buffer.&lt;br /&gt;It also has flags determining the type of the vertexbuffer (dynamic or static) and if it's "dirty".&lt;br /&gt;&lt;br /&gt;If a PipelineBuffer has the dirty flag, it means the data inside it has changed (like a quad has got a new light and can't be batched with the others anymore) and has to be re-initialized.&lt;br /&gt;Quads in a dirty buffer are dumped back into the free quad list and re-assigned.&lt;br /&gt;&lt;br /&gt;The dirty mechanism is done in a simple manner: a quad contains an event which is triggered whenever a value which makes batching different is changed (light, material, texture or dynamic/static flag). When adding a quad to the PipelineBuffer, the buffer adds it's handler for the event.&lt;br /&gt;&lt;br /&gt;Comparing to the earlier batching, without indexbuffers and without batching the 15 or so units which were also rendered: &lt;br /&gt;1. No batching, 20x20 map, about 15 units - 45 FPS&lt;br /&gt;2. Batched 20x20 map, non-batched 15 units - 100-150 FPS&lt;br /&gt;3. Batched 20x20 map and 15 units, with IndexBuffers - 650-750 FPS!&lt;br /&gt;&lt;br /&gt;1. used 20 * 20 + 15 = 415 DrawPrimitive calls&lt;br /&gt;2. used 16 DrawPrimitive calls&lt;br /&gt;3. used 2 DrawIndexedPrimitive calls (units in a dynamic buffer, if not, one call)&lt;br /&gt;&lt;br /&gt;All this good.. and something bad too: lightning broke up. For some reason, tiles using Diffuse lights show up in black now, no matter what I try. Any input welcome.&lt;br /&gt;Using Emissive lightning for now, which works just fine.&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Edit 10. Jun: About matrix translations&lt;/b&gt;:&lt;br /&gt;Matrix translations are replaced with "vertex translations". I still use a location Vector3 structure, but I don't apply a World translation. Instead, I offset the vertices in model space when defining them. Works just as fine. Using a matrix translation would yet again need me to separate things from bathing.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And here's some links related...&lt;br /&gt;&lt;a href="http://dotnet.org.za/kevint/articles/Flags.aspx" target="_blank"&gt;Bitwise Flags with Enums (samples in C#,VB.NET and TSQL)&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.gamedev.net/community/forums/topic.asp?topic_id=373793&amp;whichpage=1??" target="_blank"&gt;GameDev.net forum post on efficient rendering&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.gamedev.net/reference/articles/article1972.asp" target="_blank"&gt;A C++ article on drawing 2D in D3D using quads.. has some quad-batching examples&lt;/a&gt;&lt;br /&gt;&lt;a href="http://blog.monstuff.com/archives/000040.html" target="_blank"&gt;A very deep look into C# delegates and events&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114993875094431663?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114993875094431663/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114993875094431663' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114993875094431663'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114993875094431663'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/implementing-batching.html' title='Implementing batching'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114990230992268424</id><published>2006-06-10T03:50:00.000+03:00</published><updated>2006-06-10T04:18:29.993+03:00</updated><title type='text'>Google Analytics</title><content type='html'>A friend recently told me about a thing called "Google Analytics".&lt;br /&gt;&lt;br /&gt;It's yet again something intresting from google. This time it's a traffic analyzer.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Basically you just insert a small javascript block in the end of the page you want it to track. After that you can look at the statistics from your google analytics page.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It tracks quite many things and gives pretty detailed reports. In addition to the usual there's a few more special things too.&lt;br /&gt;&lt;br /&gt;-Visits and page view&lt;br /&gt;-New and returning visitors&lt;br /&gt;-Source of the visitors (the referer page)&lt;br /&gt;-Visitor countries&lt;br /&gt;-Top search engine keywords&lt;br /&gt;-Top entrance/exit/content pages&lt;br /&gt;-Lots of marketing related things&lt;br /&gt;-Browser versions, Platforms (Win/Linux/etc), Screen resolution, Screen colors, Languages, Java enabled, Flash version, connection speed, hostnames&lt;br /&gt;&lt;br /&gt;Lots of optimization reports.. on content, marketing and such. &lt;br /&gt;and much more&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You can apply for an account at their page at &lt;a href="http://www.google.com/analytics/home/" target="_blank"&gt;www.google.com/analytics/home/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114990230992268424?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114990230992268424/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114990230992268424' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114990230992268424'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114990230992268424'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/google-analytics.html' title='Google Analytics'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114973327204432540</id><published>2006-06-08T05:15:00.000+03:00</published><updated>2006-06-08T05:32:42.356+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Tilemap rendering optimization</title><content type='html'>Getting rather horrible frame rates with lot's o' tiles, I decided to yet again foray into optimizing the rendering procedure...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For now what I've done...&lt;br /&gt;&lt;br /&gt;I added a DumpVerts function into my Quad class. You give it a list as a param and it dumps the verts of itself into the list, transformed to the coordinates of the quad.&lt;br /&gt;&lt;br /&gt;When the TileEngine class renders the map for the first time, it just initializes a huge VertexBuffer, dumps all the tile verts there, sets dumped flag to true... and that's it.&lt;br /&gt;&lt;br /&gt;Gained 100 more FPS, which keeps fluctuating though... and the textures are b0rked for now at least... &lt;br /&gt;&lt;br /&gt;The texture breakdown is probably caused by the fact that I use TriangleFans for rendering quads... and it would look like it tries to render a gigantic trianglefan.&lt;br /&gt;So now I need to change the method I render the quads... very much completely. Bahhh. Why does anyone even bother to write tutorials where you do trianglefans when you'll eventually run into the fact that you get shit FPS and you need to batch things because a billion DrawPrimitves calls cause huge overhead.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Did also all the small things like reducing repeated device state sets etc.&lt;br /&gt;&lt;br /&gt;I still don't want to get 40-140 FPS with a 20x20 map and a bunch of units in it. Bah. And the textures are broken... except for units which aren't using the dump-render method... yet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114973327204432540?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114973327204432540/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114973327204432540' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114973327204432540'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114973327204432540'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/tilemap-rendering-optimization.html' title='Tilemap rendering optimization'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114956093439531326</id><published>2006-06-06T04:25:00.000+03:00</published><updated>2006-06-06T05:30:30.133+03:00</updated><title type='text'>Stacking</title><content type='html'>I'm doing some major rework on the graphical side of my game.&lt;br /&gt;&lt;br /&gt;The units for example, will need indicators for health or such that will stay with their own graphic when they move. I got that worked out, made a QuadStack class and a new Quad class with a dynamic vertexbuffer and some other optimizations on rendering. I'll probably replace the rendering in Plane object by inheriting it from Quad.&lt;br /&gt;&lt;br /&gt;So anyway the QuadStack is basically an object which has a position in the world and a render method. Calling render first moves the world matrix to the stack's position and then calculates the positions for the quads in the stack. Their positions are all relative to the stacks position. (Stacks world matrix multiplied by Quad's world matrix)&lt;br /&gt;&lt;br /&gt;I should probably make the stack act as a hit detector too, maybe allow it to forward click detection into the quads inside it as that would probably be useful.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The next thing on the road to graphical glory and photo-realistic effects is making an animation class, for the units and such need to have different types of animations. Idle, moving, etc.&lt;br /&gt;&lt;br /&gt;I made a simple interface on top of my current method of exposing textures to the renderable objects, so I can have a static texture which will use the same methods or an animation which also uses the same methods, but returns different textures as the animation progresses. A very good idea, I'd dare to say!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I also made some sample code, yet again as people asked for help at #C#...&lt;br /&gt;&lt;a href="http://admins.fi/~eagleeye/detectdclick.cs" target="_blank"&gt;Detecting double clicks&lt;/a&gt;&lt;br /&gt;&lt;a href="http://admins.fi/~eagleeye/hl1query.cs" target="_blank"&gt;A method for parsing Half-Life 1 server query replies&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Double click detection code could use something to reset the click tick counter to zero after a doubleclick to prevent triple clicks and such causing more double click detects and the serverquery code could... well, use a more functional approach as there's lots of repeated code... but it works and if you care, you can refine it yourself and maybe learn something in the process.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On the other news, intresting search queries in google have landed people to my site: &lt;br /&gt;intitle:index.of mp3 albums -htm -html -php -asp last modified&lt;br /&gt;parent directory mp3 or wma or ogg or wav best_of or bestof or&lt;br /&gt;&lt;br /&gt;Maybe I should add some pr0n-strings and metakeywords to get more visits. Har.&lt;br /&gt;Anyway, I added a "use opera" button to the site, because it is a superior browser. Yes yes, you don't think so. Maybe you should check the feature list on Opera's beta 9? Maybe you should &lt;a href="http://my.opera.com/zetto/affiliate/" target="_blank"&gt;try it&lt;/a&gt;!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Also - AdSense - Just for fun. Let's see what happens.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114956093439531326?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114956093439531326/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114956093439531326' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114956093439531326'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114956093439531326'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/stacking.html' title='Stacking'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114945824551695302</id><published>2006-06-05T00:39:00.000+03:00</published><updated>2006-06-05T00:57:25.546+03:00</updated><title type='text'>Buggy</title><content type='html'>No, not like the one you drive. Buggy &lt;i&gt;code&lt;/i&gt;! (ha-ha)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I managed to do some work on my game project again. I've lately been badly distracted by the Hoff and his talking car and an anime series called Overman King Gainer.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://admins.fi/~eagleeye/gameengine.JPG" target="_blank"&gt;Here&lt;/a&gt; and &lt;a href="http://admins.fi/~eagleeye/mapedit.JPG" target="_blank"&gt;here&lt;/a&gt; are the latest screenshots of my project.&lt;br /&gt;&lt;br /&gt;As you can see from the second picture, I've continued developing the map editor to the point where you can actually insert units (and structures, had I defined any - but they're not very finished yet) to the map. You can also define the players in the map and victory conditions (which do nothing at the moment, but they can be defined and saved/loaded anyway)&lt;br /&gt;&lt;br /&gt;I thought I had yet again broken the picking code.. the units didn't get selected. In the end I noticed I had made some stupid mistakes.&lt;br /&gt;&lt;br /&gt;1. the game tried to load the units owner from the wrong XML attribute&lt;br /&gt;2. the game tried to assign players to the units before the players were loaded&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There we see again. My code sucks! ;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And I'm still having problems with the editor flickering and having glitches because of the DirectX-rendered panel. I had to resort to a hackyish measure to make a ColorDialog visible! (The Panel is hidden when the dialog is visible)&lt;br /&gt;&lt;br /&gt;Seems MDX-knowledge is not very common...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114945824551695302?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114945824551695302/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114945824551695302' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114945824551695302'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114945824551695302'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/buggy.html' title='Buggy'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114944026111488307</id><published>2006-06-04T19:43:00.000+03:00</published><updated>2006-06-04T19:58:23.903+03:00</updated><title type='text'>Google ebook hack</title><content type='html'>It's quite intresting how google can find massive amounts of ebooks on various subjects... if you just know how!&lt;br /&gt;&lt;br /&gt;Here's a trick..&lt;br /&gt;&lt;br /&gt;intitle:"index of /" KEYWORD ebooks size description date -filetype:html -filetype:htm&lt;br /&gt;&lt;br /&gt;Replace keyword with your subject (for example, DirectX)&lt;br /&gt;&lt;br /&gt;So you just type that into google and.. bang.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;What's the secret behind all of that? Well, as you might know, usually file lists in webpages start with the big title "Index of /something".. so we want pages with that in the title (intitle:).. also, to filter off bogus results, we add words "size" "description" and "date" to the search.. as those words usually appear in file lists.&lt;br /&gt;&lt;br /&gt;The work ebooks is used to find filelists with word "ebooks" in them. Change it if you want. The two -filetype parameters are also used to filter out bogus results... filelists do not appear as .html or .htm files, you know.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Google can be used in a myriad of ways. It's just the trick of knowing what to type in. Some people even say that you can find &lt;i&gt;anything&lt;/i&gt; with it... which I don't really believe.&lt;br /&gt;&lt;br /&gt;Well anyway, check out &lt;a href="http://www.fravia.com" target="_blank"&gt;www.fravia.com&lt;/a&gt;.. that site contains huge amounts of information on searching the web. I found that ebook search trick from that site too, although I applied another trick a bit to come up with it.&lt;br /&gt;&lt;br /&gt;If you're a lazy bastard who can't figure out things yourself, &lt;a href="http://johnny.ihackstuff.com/" target="_blank"&gt;j0hnny has a large google hack database&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114944026111488307?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114944026111488307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114944026111488307' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114944026111488307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114944026111488307'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/google-ebook-hack.html' title='Google ebook hack'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114929210475053397</id><published>2006-06-03T02:39:00.000+03:00</published><updated>2006-06-03T02:48:24.760+03:00</updated><title type='text'>Sudden code-rot?</title><content type='html'>I ran into a really weird error today while trying to make some progress with my game.&lt;br /&gt;&lt;br /&gt;It would just keep throwing an InvalidCallException on the Device creation in the engine. I had done &lt;i&gt;no&lt;/i&gt; changes to the code, no nothing.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I finally found out that in the code where PresentParameters for the Device are initialized, the Windowed property is no where set to true if the app runs in windowed mode!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And it had worked before! What on earth deleted a line or just decided to require it, all of a sudden? I had installed Hitman: Blood Money, and after that I hadn't compiled the game nor ran it... and as far as I know, Hitman didn't install any new DX binaries.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The InvalidCallException isn't very helpful. Not at all. It doesn't even point out what &lt;i&gt;might&lt;/i&gt; have gone wrong...&lt;br /&gt;&lt;br /&gt;I know that there's the DirectX debug version and such, and I tried it, but I didn't find a way to see what kind of messages it gave. I read they could be set to be visible from project props in VS and going to debug and setting "Allow unmanaged debug" or something like that... well guess what, there was nothing like that in VS Express. Gahh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114929210475053397?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114929210475053397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114929210475053397' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114929210475053397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114929210475053397'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/06/sudden-code-rot.html' title='Sudden code-rot?'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114895428365168750</id><published>2006-05-30T04:30:00.000+03:00</published><updated>2006-05-30T04:58:03.706+03:00</updated><title type='text'>Type Type Revolution</title><content type='html'>I just got the most awesome idea in a while!&lt;br /&gt;&lt;br /&gt;Combine Dance Dance Revolution with learning to type.&lt;br /&gt;"..uhh what?" I hear you say..&lt;br /&gt;&lt;br /&gt;You probably know that in DDR (or StepMania for PC) you get those arrows pointing which key to push/step/whatever.&lt;br /&gt;&lt;br /&gt;Replace those arrows... with &lt;i&gt;letters&lt;/i&gt; and you get Type Type Revolution!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now that would be an intresting game. It might be confusing though with all the letters instead of the arrows, but I think it could be done and if it had lots and lots of songs available, like StepMania has at BemaniStyle, it would probably be a very intresting way of learning to type faster.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114895428365168750?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114895428365168750/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114895428365168750' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114895428365168750'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114895428365168750'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/type-type-revolution.html' title='Type Type Revolution'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114870129072131554</id><published>2006-05-27T06:37:00.000+03:00</published><updated>2006-05-27T06:41:30.793+03:00</updated><title type='text'>Random ideas</title><content type='html'>Here's a bunch of things I have written down about my game with &lt;a href="http://www.zhornsoftware.co.uk/stickies/" target="_blank"&gt;Stickies&lt;/a&gt; (they're floating on my desktop)&lt;br /&gt;&lt;br /&gt;Warning, very "raw" text :]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Should units contain a function which generates a data-list of the unit? Or should there be a pre-set class which displays a unit data sheet and it would just be passed a unit as a reference? Probably the latter is better&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Units could kind of have some interfaces like IArtillery/IRanged, ITransport and INaval or something? Maybe not Naval...do it with movementpenalties instead.&lt;br /&gt;&lt;br /&gt;&lt;i&gt;note: MovementPenalties is a bunch of values in the game used to determine whether unit can move over a certain terrain and if it costs more than normal&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Anyway, interfaces would allow some kind of implementation&lt;br /&gt;&lt;br /&gt;Another way would be to implement this all into the unit class itself, which would allow for a versatile XML-definition for them. To allow versatile definition but separate functionality, separate classes would be needed instead of Interfaces, eg. ArtilleryUnit, TransportUnit&lt;br /&gt;&lt;br /&gt;With interfaces, however, you could have a transport unit which would also be artillery... =)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Optimizing idea for Tile-rendering&lt;br /&gt;&lt;br /&gt;- Use one tile for a certain type of tile&lt;br /&gt;- Move the single tile around with matrices&lt;br /&gt;- eg mountain tile, grass tile and blah blah... then it gets moved around&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Currently every tile is different - 14x14 map -&gt; 196 tiles... and there are like 4 or so different kinds. I could just store a List&lt;Vector3&gt; of the locations and maybe save something?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114870129072131554?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114870129072131554/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114870129072131554' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114870129072131554'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114870129072131554'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/random-ideas.html' title='Random ideas'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114869267630205647</id><published>2006-05-27T04:11:00.000+03:00</published><updated>2006-05-27T04:20:30.923+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Docking</title><content type='html'>Someone asked if it's possible to "dock" other windows to your form in #C# channel in Quakenet... The idea was so intresting I had to try it out myself since he didn't seem to have any idea on how it could be done.&lt;br /&gt;&lt;br /&gt;Looking at MSDN is always helpful, so I started looking for native Windows-functions for changing the position of a window.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/winui/winui/windowsuserinterface/windowing/windows.asp" target="_blank"&gt;Here is a list of native Windows-functions and structs and other stuff at MSDN&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Using P/Invoke in C#, I made an app which uses GetWindowPlacement, GetClientRect and SetWindowPos to sort/dock all windows that are visible and not maximized. It uses .NET built in System.Diagnostics.Process to get a list of all processes and uses the MainWindowHandle property to check if the process has a window.&lt;br /&gt;&lt;br /&gt;You can find the &lt;a href="http://iikeli.ath.cx:1337/Docking.zip" target="_blank"&gt;source code and a binary of the application here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I tried to add useful comments to the source, so even if you're not very used to calling native windows functions and other things, you can hopefully learn something.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now, it does not exactly &lt;i&gt;dock&lt;/i&gt; things to itself... it just moves other forms next to it. And the algorithm which does that is not very good.. does it's job, but it could be done more effectively and such.&lt;br /&gt;&lt;br /&gt;For "true" docking, you probably would have to add something which rearranges the other forms if you move the main form. Also you'd have to add something which monitors other processes running to see if there's a new window which needs to be docked or a process has been shut down and should be removed from the docking list.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114869267630205647?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114869267630205647/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114869267630205647' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114869267630205647'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114869267630205647'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/docking.html' title='Docking'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114869220689090156</id><published>2006-05-26T09:32:00.000+03:00</published><updated>2006-05-27T04:10:06.960+03:00</updated><title type='text'>Haado Disuku</title><content type='html'>I found a bunch of old Quantum Fireball disks lying around today. I thought I'll install them to my server box, even though they're something like 3-4 gigs each.&lt;br /&gt;&lt;br /&gt;It's quite painful to install disks into older computers... The disk I installed the linux on the server is a 40 gig disk. The BIOS didn't seem to support disks that big, so I had to figure out how to make it work. Didn't have the slightest clue on what mobo the box has, so I couldn't upgrade the BIOS. Luckily I found out that I could limit the size of the disk to 32 gigs by setting the jumpers to different locations.&lt;br /&gt;&lt;br /&gt;It's always those jumpers. Rather annoying to try getting them out from the slots where they usually are in new disks: inside a connector-like thing...&lt;br /&gt;&lt;br /&gt;So I was installing those Quantum disks, which are very reliable by the way, I've had them for years, years and more years and they still work perfect. The disks wouldn't work, not at all at first. I finally realized the jumpers. If a hard disk doesn't work, it's the jumpers (or if it makes a funny noise when you shake it, it's broken ;) )... &lt;br /&gt;&lt;br /&gt;Why aren't the jumpers in new disks in a similar place they were on the Quantums? They were right there, easily removable, on the circuitry in the disk! Not jammed and crammed into some small slot like they are nowadays...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The next thing was I wanted to check what was on the disks.. and like I had an idea how to mount FAT16, FAT32 and NTFS partitions on Linux... well, google is my friend so that wasn't a big of a problem anyways.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now I can host more warez! har!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114869220689090156?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114869220689090156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114869220689090156' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114869220689090156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114869220689090156'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/haado-disuku_26.html' title='Haado Disuku'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114853852620374561</id><published>2006-05-25T09:01:00.000+03:00</published><updated>2006-05-25T09:28:46.280+03:00</updated><title type='text'>Programmer deprived of sleep - Police suspects blood money is involved</title><content type='html'>Someone might guess from the title - I've been playing Hitman - Blood Money quite lot lately. It's the 4th game in the Hitman-series and a good step forwards yet again, in terms of graphics and gameplay. It's pretty cool to be able to make your kills look like "accidents" by pushing someone over a ledge for example.&lt;br /&gt;&lt;br /&gt;Related to hitmen, &lt;a href="http://www.hitman.us" target="_blank"&gt;you can hire one from here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So there hasn't been anything new in the programming field for these days... Today I continued my project again though. I've implemented building new units now and a menu where you can select the map you want to play, which is rather crude but does it's job.. same goes for pretty much everything, I'll do something about the graphics and such when the functionality is done otherwise :)&lt;br /&gt;&lt;br /&gt;Now the task I took on today is updating the map editor to allow placing game objects... Units and structures. To do that, I need to do quite much other work not directly related to the task at hand: &lt;br /&gt;Need to update map-format for object data - Simple, but need to do a parser for that too&lt;br /&gt;Because the objects need to know which side they belong to when they are loaded, I need to change the format even more - Add details of the players involved&lt;br /&gt;As the player details are saved into the map, that info needs to be changeable from the editor.. and also the game itself needs to create the players when loading a map and so on&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The end result.. I'm going to make some kind of a Mission data holder class now, which will contain all the small details.. the players, the tile map, the unit data etc... also victory conditions, which I'll probably be adding later as they need something to base the win calculations on.&lt;br /&gt;&lt;br /&gt;The editor has to be able to save Missions and the game has to be able to load Missions.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;New music. I Love Disco Diamonds Vol. 39 which was released quite recently is awesome... definite recommendation for anyone who likes old synth/disco music.&lt;br /&gt;&lt;br /&gt;And to whoever named a crazy hypertechno/eurobeat album "Shibuya Women's Pro-Wrestling Original Soundtrack"... What were you high on? I'm imagining women wrestling to high BPM techno music... @_@&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114853852620374561?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114853852620374561/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114853852620374561' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114853852620374561'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114853852620374561'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/programmer-deprived-of-sleep-police.html' title='Programmer deprived of sleep - Police suspects blood money is involved'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114825056909675454</id><published>2006-05-22T01:17:00.000+03:00</published><updated>2006-05-22T01:29:29.163+03:00</updated><title type='text'>Menus and stuff</title><content type='html'>I got a very simple menu system working finally.. although for some reason Direct3D.Font throws an exception when the application closes.&lt;br /&gt;&lt;br /&gt;It's just a bunch of colored blocks and some text in them, drawn by a bunch of generic drawing functions I wrote.. faster than the old crap ones, yes. They are coupled with a Menu class which handles clicks and returns values if the user clicked on a button on the menu.&lt;br /&gt;&lt;br /&gt;Also doing some clean-up work on the main game "State" which contains the functionality to draw the map, detect clicks and other crap.. States are basically something which can be given to the Engine, which then calls the Render and Think methods in the state... So one can have a bunch of states, like a "Main menu state" which draws a main menu like thing and contains the logic for everything that happens there and another state class which handles the game itself or something like that.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://students.osao.fi/~b3haja01/tdengine.jpg" target="_blank"&gt;Here's a screenshot&lt;/a&gt; of the game.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now I need to rework some of the game state mechanics since it was originally somewhat quickly written just to test the engine and most of the functionality was just bolted on top of it later... so it needs clean up and other work.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;on the IRL side of things, only two weeks of school to go... I have no idea what I'm gonna do when the summer holiday begins... I'll probably sleep too much, stay up too long and stay in too much and look pale in the autumn compared to everyone else.. "So what have you done this summer?" - "Um, I was coding C# and IRCing"&lt;br /&gt;&lt;br /&gt;Someone donate me a laptop and a WLAN switch/router so I can go outside and code there in the sunshine ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114825056909675454?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114825056909675454/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114825056909675454' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114825056909675454'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114825056909675454'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/menus-and-stuff.html' title='Menus and stuff'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114799800958612198</id><published>2006-05-19T03:17:00.000+03:00</published><updated>2006-05-19T03:20:09.596+03:00</updated><title type='text'>Opera will be the web-browser bundled with Wii</title><content type='html'>According to a press-release from Opera Software, their browser will come with Nintendo's Wii (ex. Revolution).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://opera.com/pressreleases/en/2006/05/10/" target="_blank"&gt;http://opera.com/pressreleases/en/2006/05/10/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Another one for Opera in the browser wars! I've always said it's the best browser around ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114799800958612198?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114799800958612198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114799800958612198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114799800958612198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114799800958612198'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/opera-will-be-web-browser-bundled-with.html' title='Opera will be the web-browser bundled with Wii'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114796936657896671</id><published>2006-05-18T19:13:00.000+03:00</published><updated>2006-05-18T19:22:46.613+03:00</updated><title type='text'>Generating textures on-the-fly</title><content type='html'>I needed something to debug my pathfinding. I wanted to see how it advances when finding the path to a tile.&lt;br /&gt;&lt;br /&gt;I thought... "I'll have it set the tile's texture to something else to see when it's doing what tile"... Okay. I made a bunch of graphics with a number on them and a counter on the pathfinder which changed the texture to one with a same number as the current loop was.&lt;br /&gt;&lt;br /&gt;At first I had five numbered textures.. then I needed more. It was kind of tedious to create them in paint so I figured.. you can create a Texture from a Bitmap... What if I created the bitmap on the fly.. with GDI!&lt;br /&gt;&lt;br /&gt;Ta-dah, I present you: generating textures on the fly with System.Drawing-classes.&lt;br /&gt;The following example is "Using" System.Drawing and Microsoft.DirectX.Direct3D namespaces so if you can't find the classes, they should be somewhere in those.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//First, create a new Bitmap&lt;br /&gt;Bitmap bmp = new Bitmap(20, 20);&lt;br /&gt;&lt;br /&gt;//Create pens for drawing&lt;br /&gt;//A black one for text&lt;br /&gt;Pen p = new Pen(Color.Black);&lt;br /&gt;&lt;br /&gt;//A white one for background&lt;br /&gt;Pen p2 = new Pen(Color.White);&lt;br /&gt;&lt;br /&gt;//Create a Graphics object from the Bitmap&lt;br /&gt;//Dont worry, you can use a Bitmap even though&lt;br /&gt;//it says Image in the parameter list&lt;br /&gt;Graphics g = Graphics.FromImage(bmp);&lt;br /&gt;&lt;br /&gt;//Create a font&lt;br /&gt;System.Drawing.Font font = new System.Drawing.Font(&lt;br /&gt;   System.Drawing.FontFamily.GenericSerif,10);&lt;br /&gt;&lt;br /&gt;//Create a Rectangle for filling the whole bitmap&lt;br /&gt;Rectangle rect = new Rectangle(0, 0, bmp.Width, bmp.Height);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//Fill with white&lt;br /&gt;g.FillRectangle(p2.Brush, rect);&lt;br /&gt;&lt;br /&gt;//Draw some text with black in the top corner&lt;br /&gt;g.DrawString("10", font, p.Brush, 1, 1);&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;//Now create a texture from the bitmap and you're done!&lt;br /&gt;Texture t = new Texture(device, bmp, 0, Pool.Managed);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Now obviously this isn't very fast. Actually not fast at all... but it can be used for purproses like I did when the speed is not a problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114796936657896671?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114796936657896671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114796936657896671' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114796936657896671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114796936657896671'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/generating-textures-on-fly.html' title='Generating textures on-the-fly'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114782988196560787</id><published>2006-05-17T04:59:00.000+03:00</published><updated>2006-05-17T04:38:02.023+03:00</updated><title type='text'>A static engine</title><content type='html'>Earlier today.. or actually yesterday.. I was working on my game project again. It's going to be a small strategy game, kind of like Advance Wars. So anyways, I'm in the phase where I'm figuring out things like units and structures... how they will be done etc.&lt;br /&gt;&lt;br /&gt;I have a base class for game objects, aptly named "GameObject". For now, there's also a GameObjectType enum, which can be two different things: either "Unit" or "Structure". I have my unit code in quite good order at the moment. The game loads unit data from an XML file, which defines the unit's name, texture, movement, weaponry and armor. The data is then saved into a container class, from where you can get a certain unit's details with the unit's name, eg. "Tank" or "Infantry" or whatever.. the class returns a struct, which has a method for generating a Unit-object from the data. The Unit object is an actual renderable class, which contains all the logic and related. I've used some units in my tests, and they can be moved around the map, when you select one, you'll get a highlight of the area where it can move to and so on.&lt;br /&gt;&lt;br /&gt;Now, I was making a similar class for structures... Structures in my game would be something like... factories, where you could build tanks, airbases for building jets and helis and so on..&lt;br /&gt;So obviously, a structure must be able to create a whole new unit into the world.. if it wants to, not every structure will do that. While implementing that, I ran into several problems. Firstly, the object manager, which is used to handle the units in the game.. eg. when the game is in "select unit" state, mouse clicks trigger a check in the object manager which then checks if you clicked on a unit or not and returns the unit in question if you did and so on... the problem with this was that the structures needed a reference to this.. well, no problem.. I'll just pass it to the structure-class constructor and save it. Okay, that's solved.&lt;br /&gt;&lt;br /&gt;Next.&lt;br /&gt;The actual game engine's device for rendering stuff. It would need that too! Guh.. I got tired of having to pass stuff not really even related to the object, so I thought that I'll try to see if I can modify the engine so that it's accessible from everywhere in the code...&lt;br /&gt;&lt;br /&gt;&lt;i&gt;so I made it a static class&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;I had tried to do this earlier in another project which I scrapped later due to loss of intrest and time... and failed miserably. The engine would always get stuck into the main loop, never even rendering anything. I had no idea what was the problem back then.&lt;br /&gt;&lt;br /&gt;Now that I had succesfully already got my engine drawing into a windows forms control, a Panel to be specific, I thought that maybe I could get it working this time. Well, I did. &lt;br /&gt;&lt;br /&gt;I tried the static engine with my map editor first, because it was simply easier to change than the game itself. As I have posted earlier on, the "old" engine is built inside a form... and the game is built inside that very same form too and so on... It was a bit hasty I guess, but now I have the engine as a separate class. (guess what it's called... that's right, "Engine")&lt;br /&gt;&lt;br /&gt;There's just one problem with the editor now.. the other controls aren't drawn properly. They &lt;i&gt;are&lt;/i&gt; drawn, but they kind of disappear and aren't visible at all times and other stuff like that. I think it's probably the render loop I'm using (&lt;a href="http://blogs.msdn.com/rickhos/archive/2005/03/30/403952.aspx" target="_blank"&gt;http://blogs.msdn.com/rickhos/archive/2005/03/30/403952.aspx&lt;/a&gt;) since it's so crazily optimized for rendering with DirectX.&lt;br /&gt;&lt;br /&gt;If someone knows about fixing that, let me know.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Another fun thing I stumbled upon: SizeF.Equals(something) is stupondously more expensive to call than comparing the Width and Height properties... I had NO idea. Thank you &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=A362781C-3870-43BE-8926-862B40AA0CD0&amp;displaylang=en" target="_blank"&gt;CLR Profiler for .NET Framework 2.0&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;That's about it. For now. Back to hacking the engine and optimizing things. &lt;i&gt;And I want to be able to sleep normally again goddamnit.&lt;/i&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114782988196560787?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114782988196560787/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114782988196560787' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114782988196560787'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114782988196560787'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/static-engine.html' title='A static engine'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114744464802711166</id><published>2006-05-12T17:35:00.000+03:00</published><updated>2007-04-14T18:15:42.598+03:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Windows'/><title type='text'>Getting rid of "Restart computer now" nag screen after automatic updates</title><content type='html'>You know that thing, which keeps popping up every 10 minutes or so, asking you to restart now or later... eventually gets a timer too...&lt;br /&gt;&lt;br /&gt;Here's how to get rid of that most idiotic dialog in Windows XP I've ever seen!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Start / Run / gpedit.msc / Local Computer Policy / Computer Configuration / Administrative Templates / Windows Components / Windows Update / Re-prompt for restart with scheduled installations&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Update April 14th 2007:&lt;/b&gt; this one's been wrong so long... You have to set the above value to some arbitary number to make it take that long until it shows up again. Doesn't seem it's possible to completely get rid of it, but the maximum value 1440 or something is quite long =)&lt;br /&gt;&lt;br /&gt;Do it now, for the sake of your mental health.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114744464802711166?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114744464802711166/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114744464802711166' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114744464802711166'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114744464802711166'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/getting-rid-of-restart-computer-now.html' title='Getting rid of &quot;Restart computer now&quot; nag screen after automatic updates'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114741888459462648</id><published>2006-05-12T08:19:00.000+03:00</published><updated>2006-05-12T10:28:04.700+03:00</updated><title type='text'>A*</title><content type='html'>A*... does that ring any bells? It should, if you've been playing with pathfinding algorithms.&lt;br /&gt;&lt;br /&gt;I made an incredibly crap implementation of that into my tile based game thing. Incredibly crappy, eg. it takes ages to find a path sometimes... but hey, it &lt;i&gt;does&lt;/i&gt; find the path, even though it adds some 20.000 tiles to the lists even though the map doesn't contain that many... &lt;small&gt;I know it's buggy, yes&lt;/small&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I was playing with an idea of a "raster renderer" thing made with Direct3D. As you might know, you can draw vertices and wire-frame triangles too... I thought that what if you'd render lines with that kind of rendering, like you'd draw lines with GDI or anything... and raw pixels with single vertices.&lt;br /&gt;&lt;br /&gt;Something which could draw filled rectangles and stuff would probably be very possible. Need to look into that after I've fixed the pathfinding code. I could use that to render simple graphics.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Another night spent with no sleep. I need to do something about my sleeping cycles. The next thing I'll be doing now is probably hit the shower and go to the store to grab some Pepsi or something :]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114741888459462648?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114741888459462648/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114741888459462648' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114741888459462648'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114741888459462648'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/blog-post.html' title='A*'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114703039321166937</id><published>2006-05-07T22:17:00.000+03:00</published><updated>2006-05-07T22:33:13.253+03:00</updated><title type='text'>Keyboard hooks revisited</title><content type='html'>I realized there's an even simpler way to make a global keyboard hook than the way I demonstrated earlier, though this method requires DirectX.&lt;br /&gt;&lt;br /&gt;Using the DirectInput Device class for acquiring the keyboard you can create a global keyboard hook. It's very simple, just a matter of few lines of code&lt;br /&gt;&lt;br /&gt;The following code could be used for hooking the keyboard&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using DXI = Microsoft.DirectX.DirectInput;&lt;br /&gt;&lt;br /&gt;//this is taken from my keyboard handler class&lt;br /&gt;//keyboard is a DXI.Device in the class.&lt;br /&gt;public void AcquireKeyboard(System.Windows.Forms.Control parent)&lt;br /&gt;{&lt;br /&gt;keyboard = new DXI.Device(DXI.SystemGuid.Keyboard);&lt;br /&gt;keyboard.SetDataFormat(DXI.DeviceDataFormat.Keyboard);&lt;br /&gt;&lt;br /&gt;keyboard.SetCooperativeLevel(parent,&lt;br /&gt;  DXI.CooperativeLevelFlags.Background |&lt;br /&gt;  DXI.CooperativeLevelFlags.NonExclusive);&lt;br /&gt;&lt;br /&gt;            &lt;br /&gt;keyboard.Properties.BufferSize = 10;&lt;br /&gt;&lt;br /&gt;keyboard.Acquire();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Reading the keyboard input could be done with the following&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;DXI.BufferedDataCollection dataCollection = keyboard.GetBufferedData();&lt;br /&gt;DXI.Key key;&lt;br /&gt;&lt;br /&gt;if (dataCollection != null)&lt;br /&gt;{&lt;br /&gt;  //loop through the keys changed&lt;br /&gt;  foreach (DXI.BufferedData data in dataCollection)&lt;br /&gt;  {&lt;br /&gt;    key = (DXI.Key)data.Offset;&lt;br /&gt;    //now we have the key&lt;br /&gt;    //do something with it here&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;In the above code, data.ButtonPressedData is 1 if the key was pressed down and 0 if the key was lifted.&lt;br /&gt;&lt;br /&gt;With this method though, you won't get an event notification when a key state is changed. You have to make a loop which checks the key state and write your own event or such.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://students.osao.fi/~b3haja01/kbman.cs" target="_blank"&gt;Here's my keyboardmanager class code&lt;/a&gt;&lt;br /&gt;I don't know if it's any good, but it works well enough at least for now... and it has events which get triggered properly. &lt;br /&gt;To acquire the KB, just call the AcquireKeyboard method with the form as a parameter and make a loop which calls Update()&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114703039321166937?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114703039321166937/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114703039321166937' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114703039321166937'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114703039321166937'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/keyboard-hooks-revisited.html' title='Keyboard hooks revisited'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114702768964715297</id><published>2006-05-07T21:01:00.000+03:00</published><updated>2006-05-07T21:48:09.713+03:00</updated><title type='text'>Tiling trouble</title><content type='html'>Last time I posted about the tile map editor thing for my engine.&lt;br /&gt;&lt;br /&gt;Now I'm in the middle of reworking the whole tile map code. There was a certain bit of problem: all the data a tile had was the texture and the name of the texture.&lt;br /&gt;&lt;br /&gt;..and the texture name part was kind of glued on top of the Plane object :p&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So now I've made a struct for tile data. It contains a name for the tile, a tile type (something like.. can go here, can't go here and such) and a TextureData struct, which contains the name of the texture and a reference to the actual Texture object.&lt;br /&gt;&lt;br /&gt;I need to do some refactoring on the tilemap classes to make it use the new data structures and so on.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Being an old C/C++ user (and PHP), I sometimes just can't get it into my head that C# passes classes as references. I always feel like I'd need to use a pointer or something like that. Honestly said it's a very useful feature to not have to do that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114702768964715297?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114702768964715297/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114702768964715297' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114702768964715297'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114702768964715297'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/tiling-trouble.html' title='Tiling trouble'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114696173634290422</id><published>2006-05-07T01:10:00.000+03:00</published><updated>2006-05-07T03:28:57.256+03:00</updated><title type='text'>More engineering</title><content type='html'>I've been working on a tile map editor today.&lt;br /&gt;&lt;br /&gt;I bound my engine into a Panel object residing inside another form... a bit hacky at the moment, as the engine itself is bound into another form. When the editor starts, you get a "ghost form" into the background which is the engine's own form :)&lt;br /&gt;&lt;br /&gt;The map editor itself is looking quite good. It loads textures from a file, saves maps into a XML format... changing tile textures is done with clicking the tile with the mouse... I like it! I'm quite surprised I even managed to get it working that well!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I had a huge problem with getting the mouse click detection working... the tile positions would just get offset so much that you'd have to click in a totally different location than the tile itself.&lt;br /&gt;&lt;br /&gt;I found out that by setting device.Transform.World = Matrix.Identity after rendering a scene fixes it. It was that simple, and I tried all kinds of weird stuff... bleh.&lt;br /&gt;&lt;br /&gt;I also had a small problem with changin the cursors coordinates from the screen coords to the applications coordinates... but after a bit of looking, there was a function on the Control class which does it for me. PointToClient(Point p)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And continuing on my earlier attempts of optimizing the rendering process...&lt;br /&gt;&lt;br /&gt;Every tile in a tilemap has a vertexbuffer, containing the vertices for it. Someone suggested that I should use a static vertexbuffer... then every tile would use the same buffer, therefore saving resources.&lt;br /&gt;Okay, so I do that...&lt;br /&gt;&lt;br /&gt;FPS with a non-static vertexbuffer = ~260&lt;br /&gt;FPS with a static vertexbuffer = ~360&lt;br /&gt;&lt;br /&gt;Nice I'd say.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There's the problem of different sized tiles though... If I were to have different sized tiles (they're all of the same size at the moment), the static buffer wouldn't work... &lt;br /&gt;&lt;br /&gt;So I added a static Size-struct, containing the size of the tile in the vertexbuffer. Every tile also has their very own size struct, which is then compared to the static one to see if the vertices in the static buffer are correct.&lt;br /&gt;If the size differs, the Plane calls it's own Reset() method which initializes the static buffer with the correct vertices.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Onwards, to where no man has gone before!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114696173634290422?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114696173634290422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114696173634290422' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114696173634290422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114696173634290422'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/more-engineering.html' title='More engineering'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114692864647220902</id><published>2006-05-06T18:14:00.000+03:00</published><updated>2006-05-06T18:17:27.333+03:00</updated><title type='text'>A new version of Windows Live Messenger</title><content type='html'>Microsoft put out a new version of Windows Live Messenger beta today.&lt;br /&gt;&lt;br /&gt;The interface has been changed to look a bit different, with some fancy graphics.&lt;br /&gt;They have also fixed the "What I'm listening to" feature to show the artist's name too. Probably other fixes too but I didn't notice anything other than the obvious :)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://students.osao.fi/~b3haja01/wlmb1.jpg" /&gt;&lt;br /&gt;&lt;img src="http://students.osao.fi/~b3haja01/wlmb2.jpg" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114692864647220902?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114692864647220902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114692864647220902' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114692864647220902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114692864647220902'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/new-version-of-windows-live-messenger.html' title='A new version of Windows Live Messenger'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114682466457898555</id><published>2006-05-05T13:15:00.000+03:00</published><updated>2006-05-05T13:27:12.826+03:00</updated><title type='text'>Picking up stuff from 3D-space with mouse rays</title><content type='html'>Okay so I finally have it figured out thanks to the nice people at microsoft.public.win32.programmer.directx.managed newsgroup.&lt;br /&gt;&lt;br /&gt;I'll just post the code here too in case someone else might someday run into a similar problem, and to be honest, there are no good examples of doing this unless you're using a Mesh object.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//Checks if point P is inside the plane&lt;br /&gt;internal bool PointIntersects(Point p, Device d, out IntersectInformation intersectInfo)&lt;br /&gt;{&lt;br /&gt;            //Create near and far vectors from the Point location&lt;br /&gt;            Vector3 near = new Vector3(p.X, p.Y, 0);&lt;br /&gt;            Vector3 far = new Vector3(p.X, p.Y, 1);&lt;br /&gt;&lt;br /&gt;            //Unproject the vectors into world coordinates&lt;br /&gt;            near.Unproject(d.Viewport, &lt;br /&gt;                           d.Transform.Projection, &lt;br /&gt;                           d.Transform.View, Matrix.Translation(location));&lt;br /&gt;            far.Unproject(d.Viewport, &lt;br /&gt;                          d.Transform.Projection, &lt;br /&gt;                          d.Transform.View, Matrix.Translation(location));&lt;br /&gt;&lt;br /&gt;            //Calculate the direction of the ray from the vectors&lt;br /&gt;            Vector3 dir = Vector3.Subtract(far, near);&lt;br /&gt;&lt;br /&gt;            //Set up the locations of the vertices &lt;br /&gt;            //in the first triangle in the quad&lt;br /&gt;            Vector3 loc1 = location;    //Bottom left&lt;br /&gt;            Vector3 loc2 = new Vector3(location.X, &lt;br /&gt;                      location.Y + size.Height, location.Z); //top left&lt;br /&gt;            Vector3 loc3 = new Vector3(location.X+size.Width, &lt;br /&gt;                      location.Y, location.Z);    //bottom right&lt;br /&gt;&lt;br /&gt;                        &lt;br /&gt;            //check for intersection&lt;br /&gt;            bool intersection = Geometry.IntersectTri(loc1, loc2, loc3, &lt;br /&gt;                      near, dir, out intersectInfo);&lt;br /&gt;&lt;br /&gt;            //If we didn't find an intersection in the first triangle, &lt;br /&gt;            //check the second&lt;br /&gt;            if (!intersection)&lt;br /&gt;            {&lt;br /&gt;                //Set loc1 to the coordinate of the top right vertex&lt;br /&gt;                loc1 = new Vector3(location.X + size.Width, &lt;br /&gt;                           location.Y + size.Height, location.Z);&lt;br /&gt;&lt;br /&gt;                //Check the other triangle                &lt;br /&gt;                intersection = Geometry.IntersectTri(loc2, loc1, loc3, &lt;br /&gt;                           near, dir, out intersectInfo);&lt;br /&gt;            }&lt;br /&gt;&lt;br /&gt;            return intersection;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I used that inside my Plane class which is used for rendering 2D-like quads.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114682466457898555?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114682466457898555/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114682466457898555' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114682466457898555'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114682466457898555'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/picking-up-stuff-from-3d-space-with.html' title='Picking up stuff from 3D-space with mouse rays'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114670519864319536</id><published>2006-05-04T03:53:00.000+03:00</published><updated>2006-05-04T04:13:18.723+03:00</updated><title type='text'>Engineering</title><content type='html'>What I've been working on lately is a 2D-engine type of thing. It's made with managed DirectX.&lt;br /&gt;&lt;br /&gt;A fake-2D that is... It uses Direct3D to create vertices in 3D-space and renders textured quads that look like 2D.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://students.osao.fi/~b3haja01/2dengine.JPG" target="_blank"&gt;Screeny&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If some smartypants thinks he can identify the game where I stole the tile graphics from, go ahead and try to guess. ;)&lt;br /&gt;&lt;br /&gt;The engine currently can render a tile map like in the screenshot... the rendering process can probably be optimized by using some trickery and made faster. The actual tile map data is loaded from &lt;a href="http://students.osao.fi/~b3haja01/Map.xml" target="_blank"&gt;a XML file like this&lt;/a&gt; and the texture data is saved in a resource file, which uses some MS defined resource file format... I made a small utility to create resource files and add/remove/extract resources to/from them and a DLL which contains the code for getting System.IO.Streams of the files inside.&lt;br /&gt;&lt;br /&gt;So now I'm trying to get "picking" to work. What's this picking? It basically means that I want to get the engine to detect what objects are under the mouse cursor in 3D-space... &lt;b&gt;which is giving me a damn headache&lt;/b&gt;. I've tried projecting the mouse coordinates into 3D space to create vectors and rays and whatever and calculating intersections... and tried projecting the quads into 2d space, which was more successful but the quad positions are a bit offset, so it's not working well enough either. HELPPpp...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;On other news, &lt;a href="http://avexnet.jp/item/sebea/disc/product/AVCD-17836.html" target="_blank"&gt;Super GT 2006&lt;/a&gt; was released today (actually yesterday as I'm posting this on 4th). The linked page contains samples... so &lt;i&gt;go go go&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And on the other other news, which are actually rather old, the fansubbing group Bakafish has been subbing &lt;i&gt;Hard Gay&lt;/i&gt; episodes. For those of you who don't know who this Hard Gay persona is, go ahead and take a look at &lt;a href="http://en.wikipedia.org/wiki/Hard_Gay" target="_blank"&gt;this wikipedia article&lt;/a&gt;... or actually, I'll just say it here: He's hilarious. 'nuff said about that.&lt;br /&gt;&lt;br /&gt;Visit &lt;a href="http://www.bakakage.net/" target="_blank"&gt;Bakakage forums&lt;/a&gt; for the episodes. You may have to register to get access to the Hard Gay forum.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;My random thought of the moment: why do most people think I'm weird, because I don't feel any need to "hunt" women? Actually even &lt;i&gt;I&lt;/i&gt; find it weird at times, since everyone says so... Come on, sex is not the only thing a woman can offer.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That's it for now.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114670519864319536?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114670519864319536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114670519864319536' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114670519864319536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114670519864319536'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/05/engineering.html' title='Engineering'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114614068350181068</id><published>2006-04-27T14:19:00.000+03:00</published><updated>2006-04-27T16:04:18.070+03:00</updated><title type='text'>Creating a global keyboard hook in C# without unmanaged code</title><content type='html'>Since every article about making a global hook with .NET had an unmanaged .dll making the hook, I'll just write here how to make one without any custom hooker DLLs.&lt;br /&gt;&lt;br /&gt;Note: .NET cannot make a global hook for other events than WH_KEYBOARD_LL or WH_MOUSE_LL&lt;br /&gt;&lt;br /&gt;With some small changes (KBDLLHookStruct to IntPtr), this code can be used for other hooks too.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Collections.Generic;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Runtime.InteropServices;&lt;br /&gt;&lt;br /&gt;namespace WinHook {&lt;br /&gt;&lt;br /&gt;public class KBHookEventArgs : EventArgs&lt;br /&gt;{&lt;br /&gt; public int HookCode;&lt;br /&gt; public IntPtr wParam;&lt;br /&gt; public KBDLLHookStruct lParam;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Structure returned by a WH_KEYBOARD_LL hook&lt;br /&gt;public struct KBDLLHookStruct&lt;br /&gt;{&lt;br /&gt; public int vkCode;&lt;br /&gt; public int scanCode;&lt;br /&gt; public int flags;&lt;br /&gt; public int time;&lt;br /&gt; public int dwExtraInfo;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;//Hook Types&lt;br /&gt;//more could be added&lt;br /&gt;public enum HookType : int&lt;br /&gt;{&lt;br /&gt; WH_KEYBOARD_LL = 13,&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;/*&lt;br /&gt;Parts of this class stolen from MSDN and modified&lt;br /&gt;*/&lt;br /&gt;public class GlobalKBHook {&lt;br /&gt; //Callback for the hook &lt;br /&gt; public delegate int KBHookProc(int code, IntPtr wParam, ref KBDLLHookStruct);&lt;br /&gt; &lt;br /&gt; protected KBHookProc kbhook = null;&lt;br /&gt; protected IntPtr hhook = IntPtr.Zero;&lt;br /&gt;&lt;br /&gt; public delegate void KBHookEventHandler(object sender, KBHookEventArgs e);&lt;br /&gt;&lt;br /&gt; public event KBHookEventHandler KBHookInvoked;&lt;br /&gt;&lt;br /&gt; protected void OnKBHookInvoked(KBHookEventArgs e)&lt;br /&gt; {&lt;br /&gt;  if(KBHookInvoked != null)&lt;br /&gt;   KBHookInvoked(this, e);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public GlobalKBHook()&lt;br /&gt; {&lt;br /&gt;  kbhook = new KBHookProc(this.CoreKBHook);&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public int CoreKBHook(int code, IntPtr wParam, ref KBDLLHookStruct lParam)&lt;br /&gt; {&lt;br /&gt;  if (code &lt; 0)&lt;br /&gt;   return CallNextHookEx(hhook, code, wParam, lParam);&lt;br /&gt;&lt;br /&gt;  KBHookEventArgs e = new KBHookEventArgs();&lt;br /&gt;  e.HookCode = code;&lt;br /&gt;  e.wParam = wParam;&lt;br /&gt;  e.lParam = lParam;&lt;br /&gt;  OnHookInvoked(e);&lt;br /&gt;&lt;br /&gt;            // Yield to the next hook in the chain&lt;br /&gt;            return CallNextHookEx(hhook, code, wParam, lParam);    &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void Install()&lt;br /&gt; {&lt;br /&gt;  int hInstance = LoadLibrary("User32");&lt;br /&gt;  hhook = SetWindowsHookEx(&lt;br /&gt;   HookType.WH_KEYBOARD_LL,&lt;br /&gt;   kbhook,&lt;br /&gt;   (IntPtr)hInstance, //IntPtr.Zero for local hooks&lt;br /&gt;   0); //zero = global hook, otherwise use local thread ID&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public void Uninstall()&lt;br /&gt; {&lt;br /&gt;  UnhookWindowsHookEx(m_hhook); &lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; //win32 api function for creating hooks&lt;br /&gt; [DllImport("user32.dll")]&lt;br /&gt; protected static extern IntPtr SetWindowsHookEx(HookType code,&lt;br /&gt;  HookProc func,&lt;br /&gt;  IntPtr hInstance,&lt;br /&gt;  int threadID);&lt;br /&gt;&lt;br /&gt; &lt;br /&gt; //win32 api function for unhooking &lt;br /&gt; [DllImport("user32.dll")]&lt;br /&gt;  protected static extern int UnhookWindowsHookEx(IntPtr hhook);&lt;br /&gt; &lt;br /&gt; //win32 api function for continuing the hook chain&lt;br /&gt; [DllImport("user32.dll")]&lt;br /&gt; protected static extern int CallNextHookEx(IntPtr hhook, &lt;br /&gt;  int code,  &lt;br /&gt;  IntPtr wParam, &lt;br /&gt;  KBDLLHookStruct lParam);&lt;br /&gt;&lt;br /&gt; //Used to find HWND to user32.dll&lt;br /&gt; [DllImport("kernel32")]&lt;br /&gt; public extern static int LoadLibrary(string lpLibFileName);&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So uhh... that should be it... unless I forgot something. I have it a bit different in my app, so.. if you run into any probs with that and can't fix it.. just ask.&lt;br /&gt;&lt;br /&gt;Basically to use that you'd do something like:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;public partial class Form1 : Form&lt;br /&gt;{&lt;br /&gt; GlobalKBHook gkbh;&lt;br /&gt; &lt;br /&gt; public Form1()&lt;br /&gt; {&lt;br /&gt;  gkbh = new GlobalKBHook();&lt;br /&gt;  gkbh.KBHookInvoked += new GlobalKBHook.KBHookEventHandler(hookCallback);&lt;br /&gt;  gkbh.Install();&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; private void hookCallback(object sender, KBHookEventArgs e)&lt;br /&gt; {&lt;br /&gt;  //do something with the args here&lt;br /&gt;  //To get the key that was pressed,&lt;br /&gt;  //Keys key = (Keys)Enum.Parse(typeof(Keys),e.lParam.vkCode.ToString());&lt;br /&gt;&lt;br /&gt;  //if the key was pressed down, e.lParam.flags is 0, if the key was lifted, 128&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Onwards, my loyal horde of wannabe-scriptkiddies who will presumably use this code to create their very own keyloggers!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;small&gt;and as a side note, I will probably post more frequently again after this small slow down... I'm again working on some intresting things.&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114614068350181068?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114614068350181068/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114614068350181068' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114614068350181068'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114614068350181068'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/creating-global-keyboard-hook-in-c.html' title='Creating a global keyboard hook in C# without unmanaged code'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114600593050655207</id><published>2006-04-26T00:24:00.000+03:00</published><updated>2006-04-26T01:58:50.676+03:00</updated><title type='text'>Thinking about reinventing the wheel (withoug knowing about it)</title><content type='html'>A meaningful (?) post for a chance.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So, I am working on a bunch of classes which could handle some simple archives... file bit like .zips for example. So I think how should I implement this?&lt;br /&gt;&lt;br /&gt;1. Maybe use XML... would work.&lt;br /&gt;2. Maybe use file streams and make your own archive format (I've done this before with C++)&lt;br /&gt;3. &lt;span style="text-decoration: line-through"&gt;Use the one I made with C++&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I scrapped the last idea since I'm quite sure that the library was quite bad :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So I thought about making it with XML... That would be simple with the .NET built-in XML classes. The parsing of files from the package would be simple too.&lt;br /&gt;&lt;br /&gt;but guess what?&lt;br /&gt;&lt;br /&gt;The good folks at Microsoft had already done this! The classes at &lt;i&gt;System.Resources&lt;/i&gt; starting with ResX.&lt;br /&gt;&lt;br /&gt;Just give the ResXResourceWriter class a filename and call AddResource to add your file data into the file. &lt;br /&gt;It takes a byte array, which can be easily obtained with &lt;i&gt;System.IO.File.ReadAllBytes&lt;/i&gt;. Just pass your soon-to-be-packaged file as a parameter.&lt;br /&gt;&lt;br /&gt;Extracting files from a ResX file is very simple too. Just use ResXResourceReader (or ResXResourceSet) and use it's GetEnumerator() with a IDictionaryEnumerator. The key will contain the resource's name and value shouod contain the byte array containing the data.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/65zzykke(VS.80).aspx" target="_blank"&gt;MSDN article on iterators&lt;/a&gt;, recommended reading about implementing IEnumerable into your own classes.&lt;br /&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/74sfy6d5(vs.80).aspx" target="_blank"&gt;MSDN - System.Resources Namespace&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Note that there's also another way to save resources in that namespace... Resource* classes, they save the stuff into a more obscure format if you like that more. I have no idea which one is better in terms of performance though.&lt;br /&gt;&lt;br /&gt;The reader and writer both can do IO.Streams too. That means you, for example, do something like decompress the package file before extracting the resources and compress it again after saving.&lt;br /&gt;&lt;br /&gt;So basically &lt;i&gt;both&lt;/i&gt; my options one and two would've just been "reinventing the wheel". Oh well, I actually like doing that ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114600593050655207?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114600593050655207/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114600593050655207' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114600593050655207'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114600593050655207'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/thinking-about-reinventing-wheel.html' title='Thinking about reinventing the wheel (withoug knowing about it)'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114547011506995249</id><published>2006-04-19T20:30:00.000+03:00</published><updated>2006-04-19T21:08:35.570+03:00</updated><title type='text'>A boring news day</title><content type='html'>Nothing has been happening lately. At least nothing worth of writing. No good links, no nothing.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;So I'll just post some randomness I ran into today...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.virtualconstructs.com/downloads/megamaneffect.shtml" target="_blank"&gt;Mega Man Effect&lt;/a&gt;&lt;br /&gt;&lt;i&gt;"The Mega Man Effect is an application that emulates an effect seen in the classic NES game Mega Man 2. When you launch an OS X Windows application, the screen goes dark, stars sweep the night sky and your application's icon is presented in a blue letter box bar with a cheesy 8-bit music introduction."&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;and for the musically curious people, &lt;a href="http://avexnet.jp/item/sebea/disc/product/AVCD-10167.html"&gt;samples from Super Eurobeat 167 can be found here&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114547011506995249?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114547011506995249/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114547011506995249' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114547011506995249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114547011506995249'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/boring-news-day.html' title='A boring news day'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114503825872100172</id><published>2006-04-14T21:03:00.000+03:00</published><updated>2006-04-14T21:13:14.403+03:00</updated><title type='text'>Thoughts about IDEs, editors and related</title><content type='html'>As I convert websites into HTML as my job, do server-side programming in PHP and client-side programming in JavaScript etc., I've used many programs to ease the process.&lt;br /&gt;&lt;br /&gt;At first I used notepad. I think most people start with notepad, and even some more experienced people use it. In my opinion, a basic editor like notepad is good for quick and dirty work, but it's nowhere near &lt;i&gt;proper&lt;/i&gt; &lt;acronym title="Integrated Developement Environment"&gt;IDE&lt;/acronym&gt;'s in terms of efficiency. Using a proper IDE also makes for better code, as the editor itself can, for example, auto-complete the ending tags in HTML.&lt;br /&gt;&lt;br /&gt;After the notepad-phase I started using Ultra-Edit. Ultra-Edit is in my opinion the best text editor around for any kind of programming. It has lots of useful features, a hex editor, built-in FTP support etc. but it still lacks the features in editors made for more specific tasks like Dreamweaver, Visual Studio or Zend Studio. I still have it somewhere, although I very rarely use it anymore.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Adobe (former Macromedia) Dreamweaver&lt;/b&gt; is the industry standard in webdesign. It's also my weapon of choice for developing webpages. &lt;br /&gt;For those of you who still think a &lt;acronym title="What You See Is What You Get"&gt;WYSIWYG&lt;/acronym&gt; editor creates cluttered and horrible code ála Frontpage, welcome to 2006: Dreamweaver's WYSIWYG features create state-of-the-art HTML and CSS based layouts which validate with &lt;acronym title="World Wide Web Consortium"&gt;W3C&lt;/acronym&gt;'s HTML and CSS validators.&lt;br /&gt;&lt;br /&gt;The code editor in Dreamweaver is probably the &lt;i&gt;best&lt;/i&gt; for coding webpages. It has autocompletion and pop-up lists for HTML, HTML tag attributes and CSS attributes etc. You can check the codes validity on the fly from the editor, check for possible compatibility errors in different browsers (eg. Netscape 3, Netscape 4, IE 6 etc.)... &lt;br /&gt;The built-in CSS editor is also a great aid in quickly creating CSS styles. Although it might not always write the most compact CSS possible, you can easily check and fix this yourself.&lt;br /&gt;&lt;br /&gt;Even though Dreamweaver is full of these advanced features, I still like to write code by hand. I use the WYSIWYG view too, though. I use it to see how does the site look. It's also very handy for laying out complex tables if you need to arrange tabular data.&lt;br /&gt;&lt;br /&gt;The site-features are also excellent. I can create a site on my own computer and have the editor automatically update the files on a remote server. This is especially useful if I'm writing PHP in Dreamweaver, as I like to keep backups on my own hard disk too. &lt;br /&gt;I probably don't need to mention this, but Dreamweaver can also work on remote files without making copies on the local machine.&lt;br /&gt;&lt;br /&gt;There's also a HTML reference, a CSS referece, a JavaScript reference... all searchable, right in the editor.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Zend Studio&lt;/b&gt; is my primary tool for developing PHP applications. There's one feature here, what you won't find in &lt;i&gt;any&lt;/i&gt; other program: &lt;i&gt;local and remote debugging for PHP&lt;/i&gt;. No more stupid if($foo == "bar") { do something } debugging code. You can see the state of the variables right from the debugger, add breakpoints to stop execution at certain parts, run one line at a time and all the other features found in debuggers like the one in Visual Studio.&lt;br /&gt;&lt;br /&gt;Other things worth mentioning is code profiling and checking. The IDE can check for typical problems, security holes etc. in your code. Has also some kind of support for HTML tag auto completion and such but I haven't really looked into that. Like I said, Dreamweaver for HTML, Zend for PHP :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now.. something I'd so dearly want...&lt;br /&gt;an editor/IDE which combines &lt;b&gt;ALL&lt;/b&gt; the best features from Dreamweaver, Zend and Visual Studio. The excellent HTML/CSS and overall features from Dreamweaver. PHP debugging and completion from Zend Studio, the simply excellent code-editor from Visual Studio. And throw in a JavaScript debugger.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Oh well. That won't probably ever happen unless Zend, Adobe and Microsoft fusion... which might not be a good thing. Microsoft Vistaloper Studio for web-design 2xxx Enterprise Edition? Guh..&lt;br /&gt;&lt;br /&gt;Obviously, as I don't know everything, I don't either have an idea if there are better alternatives out there... so... &lt;i&gt;link me&lt;/i&gt; if your opinion differs.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.zend.com/" target="_blank"&gt;Zend&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.adobe.com/" target="_blank"&gt;Adobe&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.ultraedit.com/" target="_blank"&gt;Ultra-Edit&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114503825872100172?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114503825872100172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114503825872100172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114503825872100172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114503825872100172'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/thoughts-about-ides-editors-and.html' title='Thoughts about IDEs, editors and related'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114487777499438659</id><published>2006-04-13T00:28:00.000+03:00</published><updated>2006-04-13T00:36:18.856+03:00</updated><title type='text'>Intresting coincidences....</title><content type='html'>...or I am able to affect the future!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;You may have read about &lt;a href="http://www.timesonline.co.uk/article/0,,13509-2131528,00.html" target="_blank"&gt;the capture of Bernardo Provenzano&lt;/a&gt;, a mafia-boss who had been hunted for years and years.&lt;br /&gt;&lt;br /&gt;Well, just recently I had "aqquired" a song by an artist called "Molinaro &amp; &lt;i&gt;Provenzano&lt;/i&gt;". I like the song a lot and told a friend that it's great and stuff.&lt;br /&gt;Just a day or two after, the italian police captured Bernardo &lt;i&gt;Provenzano&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;An intresting coincidence I think.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've had lots of similar intresting coincidences lately. For example, I've talked about a movie with a friend and bang, they happen to show it on TV a day or two after.&lt;br /&gt;One time I talked about a finnish movie called "Bad Boys"... a day or so after, they show "Bad Boys 2" (the american film) on TV.&lt;br /&gt;&lt;br /&gt;Coincidences or am I able to affect the future subconsciously? &lt;b&gt;WHO KNOWS!&lt;/b&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114487777499438659?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114487777499438659/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114487777499438659' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114487777499438659'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114487777499438659'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/intresting-coincidences.html' title='Intresting coincidences....'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114477217281187752</id><published>2006-04-11T18:48:00.000+03:00</published><updated>2006-04-11T19:16:13.343+03:00</updated><title type='text'>Windows Live Mail beta</title><content type='html'>And another Windows Live beta account for me..&lt;br /&gt;This time, the new version of Hotmail: Windows Live Mail&lt;br /&gt;&lt;br /&gt;Windows Live Mail is an advanced web based email. It's got all the features you'd expect from a normal webmail plus a bunch of nice advanced features.&lt;br /&gt;&lt;br /&gt;The advanced features currently work only with Internet Explorer 6 or higher, but you get a new fancy looking "old-school" webmail for browsers like Opera. The interface is quite streamlined again, it's good looking but not intrusive. Simplistic, I might say.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://admins.fi/~eagleeye/wlmail1.jpg" target="_blank"&gt;The new interface in IE 6&lt;/a&gt;&lt;br /&gt;&lt;a href="http://admins.fi/~eagleeye/wlmail2.jpg" target="_blank"&gt;The new interface in Opera 8&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The new functionality is something you could find in a Windows email client, like Outlook. Windows Live Mail is actually quite similar to Microsoft Outlook 2003.&lt;br /&gt;&lt;br /&gt;You have your mail folders on the left, mails in the middle and the currently opened mail on the right. You can also just drag and drop mails to other folders, just like you'd drag and drop files in Windows Explorer. Selecting multiple messages also works in a similar fashion as selecting multiple files in explorer (shift+click)&lt;br /&gt;&lt;br /&gt;Everything works pretty quickly, as the page is done using AJAX techniques, so the browser won't need to reload the page for example if you click on another mail.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Quite nice work, just needs support for other browsers than IE.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114477217281187752?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114477217281187752/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114477217281187752' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114477217281187752'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114477217281187752'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/windows-live-mail-beta.html' title='Windows Live Mail beta'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114470139972430725</id><published>2006-04-10T23:24:00.000+03:00</published><updated>2006-04-10T23:36:40.356+03:00</updated><title type='text'>Comparing classes and structs = pain in the ass?</title><content type='html'>I had a &lt;b&gt;huge&lt;/b&gt; problem trying to figure out &lt;i&gt;what was wrong with dictionary.ContainsKey() and dictionary[key].Contains()&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;The functions weren't working at all, might I say. I had a custom key struct and a list of classes as the value in the dictionary.&lt;br /&gt;&lt;br /&gt;The functions would never return true, even if I had just added the elements to the dictionary. Why? whywhywhywhy?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After a bit of searching from google groups, I came upon a post about something not even related which had stuff about overriding GetHashCode() and Equals().&lt;br /&gt;&lt;br /&gt;I was thinking... "Does my struct/class actually have a way to compare itself?"&lt;br /&gt;Nope. C# is clever, but not clever enough to create a GetHashCode() and Equals() function for your classes.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Here's a simple example on how to make your classes and structs easily comparable:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;class Example&lt;br /&gt;{&lt;br /&gt;  string a;&lt;br /&gt;  string b;&lt;br /&gt;&lt;br /&gt;  /* put constructor and stuff here */&lt;br /&gt;&lt;br /&gt;  public override int GetHashCode()&lt;br /&gt;  {&lt;br /&gt;    return a.GetHashCode() + b.GetHashCode();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public override bool Equals(object obj)&lt;br /&gt;  {&lt;br /&gt;    if(obj.GetHashCode() == this.GetHashCode())&lt;br /&gt;      return true;&lt;br /&gt;&lt;br /&gt;    return false;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So... basically you just make GetHashCode() take some hash values, for example from the variables in the class and return the sum. Built-in types have a working GetHashCode() defined.&lt;br /&gt;Equals() just needs to compare the hashes and.. well, that's about it. I think this is a simple and effective way.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Powering my code tonight:&lt;br /&gt;&lt;a href="http://www.hurricanefm.nl/"&gt;HurricaneFM&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.radiostaddenhaag.nl/"&gt;Radio Stad Den Haag&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Both great internet radios.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114470139972430725?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114470139972430725/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114470139972430725' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114470139972430725'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114470139972430725'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/comparing-classes-and-structs-pain-in.html' title='Comparing classes and structs = pain in the ass?'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114451462919602451</id><published>2006-04-08T19:43:00.000+03:00</published><updated>2006-04-08T19:43:51.016+03:00</updated><title type='text'>Artificial Stupidity</title><content type='html'>Today I was lurking around Dan's blog like usual. He's got intresting posts about game programming and related stuff and best of all, it's C# baby.&lt;br /&gt;&lt;br /&gt;After reading his post "Your very own Sky Net", which was about a simple AI, I wanted to do my own AI too. I'll probably do something simple. My idea at the moment was to do a small "life" simulator thing...&lt;br /&gt;&lt;br /&gt;There would be a, let's say, "mouse". It would actually move on the screen too. You could drop things to the screen, like cheese and mouse traps or rat poison.&lt;br /&gt;&lt;br /&gt;It would try to go eat the stuff you put there because it's a stupid mouse which lives only for eating. If it would eat rat poison, it'd lose HP or die. This mouse would be a respawning one though, and if it died or lost HP, it would understand that the thing it just ate isn't good for it.&lt;br /&gt;&lt;br /&gt;Well, basically something like that. I'll see if I ever get to actually coding that. Maybe I will... it seems like a fun project.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://einfall.blogspot.com/2006/04/your-very-own-sky-net.html"&gt;C# Game Development: Your very own Sky Net&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114451462919602451?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114451462919602451/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114451462919602451' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114451462919602451'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114451462919602451'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/artificial-stupidity.html' title='Artificial Stupidity'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114435725542212633</id><published>2006-04-06T23:40:00.000+03:00</published><updated>2006-04-10T15:33:31.003+03:00</updated><title type='text'>Tools for tablets</title><content type='html'>I've been experimenting with various graphics/drawing tools recently, to find out which is the best program for doing my random sketching etc. with the tablet.&lt;br /&gt;&lt;br /&gt;So far I've used Paint, Photoshop CS 2, Painter IX and Sketchbook Pro.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Paint&lt;/b&gt; is great for quick things. It's just so simple and if you don't mind rough lines, it's kinda fun too.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Photoshop&lt;/b&gt; is a good all-around tool. Although for some reason I don't really like to just plain draw stuff in it, especially when I could use Painter.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;b&gt;Painter&lt;/b&gt;.. now that's something different. I believe it's purprose-made for tablets. It's great for drawing things and painting. The brushes, pens and everything work really well and quite realistically too. Definitely worth trying out. There's a trial-version available at &lt;a href="http://apps.corel.com/painterix/home/index.html" target="_blank"&gt;http://apps.corel.com/painterix/home/index.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://students.osao.fi/~b3haja01/nyrkcol.jpg" target="_blank"&gt;Here's something I've made in Painter.&lt;/a&gt; It's incomplete and I suck.. so..&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've just recently downloaded the trial of &lt;b&gt;Sketchbook Pro&lt;/b&gt; so I haven't had lots of time to experiment with it... but it seems quite good. The interface is "optimized" for tables &lt;small&gt;(or something)&lt;/small&gt; and it's easy to use. It does seem to lack advanced features like in Photoshop and brush/pen "simulation" like in Painter, but for the purprose of sketching and just drawing things, it seems quite good. You can get a trial of Sketchbook Pro from &lt;a href="http://usa.autodesk.com/adsk/servlet/index?id=6848332&amp;siteID=123112" target="_blank"&gt;http://usa.autodesk.com/adsk/servlet/index?id=6848332&amp;siteID=123112&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://students.osao.fi/~b3haja01/haado1.jpg" target="_blank"&gt;I drew HG in Sketchbook Pro&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There's also a program by &lt;a href="http://www.xara.com" target="_blank"&gt;Xara&lt;/a&gt; which is quite good for vector-based drawing. I used it earlier to draw with the mouse... but I can't quite grasp the name. It was probably one of the easiest and the most intuitive vector drawing programs though.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That's all for now. No programming stuff... darn.&lt;br /&gt;And here's &lt;a href="http://koti.mbnet.fi/nicita/barbie.jpg" target="_blank"&gt;something fun&lt;/a&gt; (weird?).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114435725542212633?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114435725542212633/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114435725542212633' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114435725542212633'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114435725542212633'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/tools-for-tablets.html' title='Tools for tablets'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114422264602312918</id><published>2006-04-05T10:31:00.000+03:00</published><updated>2006-04-06T23:39:41.743+03:00</updated><title type='text'>Mind boggling</title><content type='html'>A friend linked me to &lt;a href="http://www.microgames.info/game_info.php?products_id=205" target="_blank"&gt;this game&lt;/a&gt; yesterday. It gave me a damn headache!&lt;br /&gt;Basically the idea is simple. You just connect the same colored blocks to each other... but it gets increasingly difficult. I've got through all the levels (30 in total). Beware, 16 and 23 = difficult as hell.&lt;br /&gt;&lt;br /&gt;and as a side note, I updated my time tracker application a bit. It now has a "fancy" tray icon which when clicked pauses or continue the current task (if one is being ran at the moment). I used &lt;a href="http://www.qtam-computer.com/download.shtml" target="_blank"&gt;QTAM Bitmap to ico&lt;/a&gt; to create the icons from a bmp made in Paint.&lt;br /&gt;&lt;br /&gt;And obviously the prog itself hides to the tray when minimized.&lt;br /&gt;&lt;br /&gt;I will probably update my project page on zTimeTracker to allow downloading later today.&lt;br /&gt;&lt;br /&gt;You did notice the project links on the right, didn't you?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There's nothing more to see here. Move it move it move iiiit.&lt;br /&gt;&lt;br /&gt;&lt;small&gt;and I started using target="_blank" in the links in posts. yay&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114422264602312918?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114422264602312918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114422264602312918' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114422264602312918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114422264602312918'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/mind-boggling.html' title='Mind boggling'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114414823713928602</id><published>2006-04-04T13:43:00.000+03:00</published><updated>2006-04-04T13:57:19.130+03:00</updated><title type='text'>State of the time</title><content type='html'>The functionality of my time tracking application is stating to shape up.&lt;br /&gt;&lt;br /&gt;At the moment, you can...&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;Fill in task details and track time spent&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Compile a list of tasks and their details (automatic)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Save and load task lists&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Generate a report of the tasks&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;It's looking good. Very good actually.&lt;br /&gt;I will probably work out some bugs in the time saving and add a tray icon and some functionality to it and release some kind of a test version for the curious to look at.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The saving and loading was easy to implement, thanks to .NET's good use of XML. The tasks are saved into a DataSet inside the app, so I just pop out the XML from the DataSet with WriteXml() to save and use ReadXml() to open. Easy!&lt;br /&gt;&lt;br /&gt;Another &lt;i&gt;very&lt;/i&gt; nifty feature about XML is XSLT. You can use XSLT to transform XML documents into other documents. And as .NET supports XSLT... there couldn't be an easier way to transform the data from the DataSet into HTML other than using XSLT to transform the XML data.&lt;br /&gt;&lt;br /&gt;I've worked with XSLT quite much at my current internship job. I've done various XML to HTML translations and one which converts XML into plain text.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you don't know what XML or XSLT are, here's some links to get you started:&lt;br /&gt;&lt;a href="http://www.w3schools.com/xml/"&gt;W3Schools XML tutorials&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.w3schools.com/xsl/default.asp"&gt;W3Schools XSLT tutorials&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.w3.org/XML/"&gt;W3C XML page&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.w3.org/Style/XSL/"&gt;W3C XSL/XSLT page&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;If you're using .NET, check MSDN's articles about System.Xml namespace.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114414823713928602?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114414823713928602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114414823713928602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114414823713928602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114414823713928602'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/state-of-time.html' title='State of the time'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114406678011922703</id><published>2006-04-03T15:19:00.000+03:00</published><updated>2006-04-03T15:19:40.533+03:00</updated><title type='text'>Game programming - the fast and fun way?</title><content type='html'>What's the fastest way to program a game? Use HTML and JavaScript!&lt;br /&gt;&lt;br /&gt;I've made plenty of experimental games with the two. Tetris, helidrop, etc.&lt;br /&gt;The latest experiment I'm working on is &lt;a href="http://admins.fi/~eagleeye/javascript/shooter/"&gt;a side-scrolling shooting game&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Why do I use HTML+JS to write games? Because it's simple! You have the graphical side and pretty much everything you need for a simple game already laid out.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The basic principle behind most of my HTML+JS games is the following:&lt;br /&gt;every object is a div-element with an "position: absolute" CSS-attribute. That way I can easily put it anywhere on the screen.&lt;br /&gt;&lt;br /&gt;Because of HTML, I can easily add graphics or colors or whatever. Just set the div's background color or background image to something.&lt;br /&gt;&lt;br /&gt;All you need to do to get a simple game loop is the following:&lt;br /&gt;Set up event handlers for keyup and keydown to get keyboard input&lt;br /&gt;&lt;pre&gt;document.body.onkeyup = keyUp;&lt;br /&gt;document.body.onkeydown = keyDown;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Set up a game-loop "ticker"&lt;br /&gt;&lt;pre&gt;function tick()&lt;br /&gt;{&lt;br /&gt;/*&lt;br /&gt;insert some function&lt;br /&gt;calls here, like&lt;br /&gt;moveObjects()&lt;br /&gt;doLogic() or something&lt;br /&gt;*/&lt;br /&gt;setTimeout('tick()',1);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;To start the game all you have to do is call tick()&lt;br /&gt;I usually have a init() function which is called in body tags onload event.&lt;br /&gt;It creates the initial objects in the game, initializes variables etc.&lt;br /&gt;&lt;br /&gt;For example, if we wanted to insert a red box in the "game field" in init()...&lt;br /&gt;&lt;pre&gt;var box = document.createElement('div');&lt;br /&gt;box.style.position = 'absolute';&lt;br /&gt;box.style.left = '200px';&lt;br /&gt;box.style.top = '200px';&lt;br /&gt;box.style.backgroundColor = 'red';&lt;br /&gt;box.style.width = '50px';&lt;br /&gt;box.style.height = '50px';&lt;br /&gt;box.id = 'player';&lt;br /&gt;&lt;br /&gt;document.body.appendChild(box);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;With the box.id given, you can easily get the object anytime you want by calling document.getElementById()&lt;br /&gt;Another way would be to save the object to a global variable, which is something I don't really like.&lt;br /&gt;I dunno which one is better performance-wise... so I'm just applying basic programming ideals: globals = bad&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now if we wanted to move the box down a bit, we could just make keyDown() check if down arrow is pressed and increase the box.style.left value. Note that there's the little part "px" after the value, so you need to make sure you don't try to add directly into the value or you'll end up with something like "200px1"&lt;br /&gt;&lt;br /&gt;I usually make a helper function to get a value without the px ending.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Maybe I'll write more about this subject later on.&lt;br /&gt;&lt;br /&gt;Some old version of a JavaScript Tetris I've made can be found &lt;a href="http://students.osao.fi/~b3haja01/"&gt;here&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114406678011922703?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114406678011922703/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114406678011922703' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114406678011922703'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114406678011922703'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/game-programming-fast-and-fun-way.html' title='Game programming - the fast and fun way?'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114405159070734974</id><published>2006-04-03T11:00:00.000+03:00</published><updated>2006-04-03T11:33:36.443+03:00</updated><title type='text'>Fading imagery</title><content type='html'>Last night while trying to fall asleep, an idea just popped into my head: A image fader made with JavaScript...&lt;br /&gt;&lt;br /&gt;&lt;i&gt;so...&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://admins.fi/~eagleeye/fade.html" target="_blank"&gt;Image fader&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Tested to work with IE, Safari,Opera 9 and Firefox. Yes, the images are blatantly stolen from around the web. Shoot me.&lt;br /&gt;&lt;br /&gt;and wtf? Opera 8 doesn't support opacity? Damn... Well, at least it rotates the images...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The idea behind the script is relatively simple, but there was a small problem with IE implementation...&lt;br /&gt;&lt;br /&gt;Basically what you do is make a structure like &amp;lt;div&gt;&amp;lt;img&gt;&amp;lt;/div&gt;, where the div will contain the image to fade to and the img will contain the image in fading.&lt;br /&gt;Fading is done by reducing the CSS opacity value or filter: alpha(opacity=something) value in IE&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Feel free to study the code or use it for something if you find it useful... a comment or link back here would be nice if you do tho.&lt;br /&gt;&lt;br /&gt;With a little work, one could easily convert that into a banner rotator with changing links when images change.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114405159070734974?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114405159070734974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114405159070734974' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114405159070734974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114405159070734974'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/fading-imagery.html' title='Fading imagery'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114401642131243563</id><published>2006-04-03T01:11:00.000+03:00</published><updated>2006-04-03T01:20:21.476+03:00</updated><title type='text'>Time tracking</title><content type='html'>As I recently posted, I've been looking for a way to easily keep track of how much time I spend on certain tasks I do, like coding a webpage for a client etc.&lt;br /&gt;&lt;br /&gt;Well, I didn't find any small and useful app to do it for me, so...&lt;br /&gt;&lt;br /&gt;&lt;img src="http://students.osao.fi/~b3haja01/ztt.JPG" /&gt;&lt;br /&gt;&lt;br /&gt;Basically it just has those fields which you fill and a clock. You can pause the clock if you stop for a while or such, and stop it and the task you've been working on will be added to the list.&lt;br /&gt;&lt;br /&gt;I'll be adding some features like loading and saving task lists, generating billing info etc.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114401642131243563?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114401642131243563/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114401642131243563' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114401642131243563'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114401642131243563'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/time-tracking.html' title='Time tracking'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114399629059574953</id><published>2006-04-02T19:40:00.000+03:00</published><updated>2006-04-02T19:44:50.610+03:00</updated><title type='text'>Superdickery</title><content type='html'>I've recently been killing my boredom by browsing the galleries at &lt;a href="http://www.superdickery.com"&gt;Superdickery.com&lt;/a&gt;, which is a site about stupid comic book covers. &lt;br /&gt;&lt;br /&gt;Mostly about Superman comics and it's spinoffs, it's a really good laugh. Definitely worth of checking out. I especially like the WW-II era propaganda themed covers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114399629059574953?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114399629059574953/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114399629059574953' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114399629059574953'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114399629059574953'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/04/superdickery.html' title='Superdickery'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114374523281765624</id><published>2006-03-30T21:57:00.000+03:00</published><updated>2006-03-30T22:02:13.483+03:00</updated><title type='text'>The Alphabet of Manliness</title><content type='html'>Maddox, the author of &lt;a href="http://www.thebestpageintheuniverse.com"&gt;The Best Page in the Universe&lt;/a&gt;, has written a book!&lt;br /&gt;&lt;br /&gt;&lt;a href="http://alphabetofmanliness.com/"&gt;The Alphabet of Manliness&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If you have no idea who Maddox is, you should definitely go check out his site. Keep in mind though, he pretty much bashes anything and everything... don't take him 100% seriously ;)&lt;br /&gt;&lt;br /&gt;In my opinion, his articles are very entertaining to read. Especially when you're bored. I might actually even buy his book sometime, even though I don't really read books other than comics and school books.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114374523281765624?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114374523281765624/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114374523281765624' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114374523281765624'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114374523281765624'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/alphabet-of-manliness.html' title='The Alphabet of Manliness'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114371144911374088</id><published>2006-03-30T00:40:00.000+03:00</published><updated>2006-03-31T22:49:22.416+03:00</updated><title type='text'>HTML rendering with GDI</title><content type='html'>I started to code my custom HTML rendering control today, aptly named zHTMLView. &lt;small&gt;Yes, I like the letter Z. Now go away.&lt;/small&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://students.osao.fi/~b3haja01/zb_gdi1.JPG" alt="zHTMLView demonstration" /&gt;&lt;br /&gt;&lt;br /&gt;I was kinda surprised how well it turned out, and this quickly!&lt;br /&gt;&lt;br /&gt;The words wrap correctly, except for bold text. If you resize the browser window, the control resizes and re-wraps text correctly etc.&lt;br /&gt;&lt;br /&gt;Oh yeah and it displays &lt;b&gt;bold&lt;/b&gt; and &lt;i&gt;italic&lt;/i&gt;. And &lt;b&gt;&lt;i&gt;bold-italic&lt;/i&gt;&lt;/b&gt;. Now how awesome is that?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The word wrap was quite easy actually.&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Take the text from a text-node&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Get width of each word one at a time&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Check if the word would go over the control's border when drawn&lt;br /&gt;&lt;ul&gt;&lt;li&gt;If it goes -&gt; new line.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;Now, to fix word wrap with B elements and to implement some Block-level element detection etc.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And on a side note, Super Eurobeat 166 was released yesterday and I got my.. uhm.. legal copy today. &lt;span style="text-decoration: line-through"&gt;It's made of win and good!&lt;/span&gt; On a second thought, I'm quite disappointed with it. Only two or so good songs.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114371144911374088?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114371144911374088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114371144911374088' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114371144911374088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114371144911374088'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/html-rendering-with-gdi.html' title='HTML rendering with GDI'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114366806620612276</id><published>2006-03-30T00:30:00.000+03:00</published><updated>2006-03-30T00:34:26.236+03:00</updated><title type='text'>Domain name</title><content type='html'>I was fantasizing about registering a domain for myself. It's not that expensive, so I thought "why not"... I could put my secondary box which runs a linux (when I get it back together, it's in pieces atm due to... a project) serving some random crap.&lt;br /&gt;&lt;br /&gt;And my host in IRC would be way cooler!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;but.&lt;br /&gt;&lt;br /&gt;Static IP&lt;br /&gt;I need a static IP. Well, no problemo, it isn't that expensive either.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;but.&lt;br /&gt;&lt;br /&gt;How am I supposed to get the IP to point to &lt;b&gt;my&lt;/b&gt; computer, not my brother's, who also uses the very same user/pass pair to connect to the 'net?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;No idea there.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Idea postponed until I get my own 10mbit line. I have a 1mbit line but I'm using a 10mbit line from my folks' place, since the same account works anywhere and you can make up to 5 connections at the same time.&lt;br /&gt;&lt;br /&gt;Bleh.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114366806620612276?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114366806620612276/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114366806620612276' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114366806620612276'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114366806620612276'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/domain-name.html' title='Domain name'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114364700107463312</id><published>2006-03-29T18:41:00.000+03:00</published><updated>2006-03-29T18:43:21.626+03:00</updated><title type='text'>Web site business</title><content type='html'>I might be getting a new web-site job involving PHP and MySQL.&lt;br /&gt;An easy and fun way of making money. Developing web sites.&lt;br /&gt;&lt;br /&gt;What's troublesome though, is trying to tell the client how much the project will cost.&lt;br /&gt;&lt;br /&gt;Even though I have quite much experience in developing sites with PHP and MySQL, I don't have that much experience in actually getting &lt;i&gt;paid&lt;/i&gt; for it. When I did stuff just for fun, I didn't think how long it actually took me.&lt;br /&gt;&lt;br /&gt;So... to get some kind of idea on what the project will cost, I have to think how long certain parts in the developement process take time, so I can calculate my fees.&lt;br /&gt;&lt;br /&gt;Tracking time spent accurately can be a bit troublesome though. Since I work from home, I might get distracted by various other things quite easily. I could obviously just look at the clock or something... but meh, there must be something better.&lt;br /&gt;&lt;br /&gt;If not - I'll make a prog myself.&lt;br /&gt;&lt;br /&gt;Something with a stopwatch and a list of tasks or something would be juuuust fine, but I haven't found one. Only bloated project management applications and such.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Another thing to do then hm... we'll see...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114364700107463312?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114364700107463312/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114364700107463312' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114364700107463312'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114364700107463312'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/web-site-business.html' title='Web site business'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114358016853392444</id><published>2006-03-29T00:03:00.000+03:00</published><updated>2006-03-29T00:11:04.210+03:00</updated><title type='text'>Heat Vision and Jack</title><content type='html'>Here's a quote...&lt;br /&gt;&lt;br /&gt;Heat Vision and Jack was created as a 1999 pilot for Fox. Written by Dan Harmon and Rob Schrab, directed by Ben Stiller, this series was passed over by Fox despite critical acclaim from those who've been lucky enough to see it.&lt;br /&gt;&lt;br /&gt;The 30 minute pilot is about an astronaut (played by Jack Black) with a medical secret who is on the run from the evil Ron Silver and the rest of NASA, with the help of a talking motorcycle called Heat Vision (voiced by Owen Wilson).&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That show &lt;i&gt;is the shit!&lt;/i&gt;&lt;br /&gt;I don't know why Fox didn't continue it ;)&lt;br /&gt;&lt;br /&gt;It succesfully mixes (parodies?) &lt;i&gt;Knight Rider&lt;/i&gt; with the &lt;i&gt;Six Million Dollar Man&lt;/i&gt; and some others which names I can't quite grasp.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://youtube.com/watch?v=6lWgXDOAJ5s"&gt;I order you to check it out!&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;small&gt;Oh yeah, the title song is "Tom Jones - Situation".. a great tune by the way&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114358016853392444?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114358016853392444/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114358016853392444' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114358016853392444'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114358016853392444'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/heat-vision-and-jack.html' title='Heat Vision and Jack'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114346317521934552</id><published>2006-03-27T15:38:00.000+03:00</published><updated>2006-03-27T15:41:07.763+03:00</updated><title type='text'>Developing a web browser, part 3</title><content type='html'>Here I am again with some new thoughts about developing web browsers...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://students.osao.fi/~b3haja01/webbr.JPG"&gt;Here&lt;/a&gt; is another screenshot of my browser. As you can see it renders a simple page okayish already.&lt;br /&gt;The scrollbar is missing. No idea why it isn't visible.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Page rendering&lt;/h3&gt;&lt;br /&gt;In it's current state, the browser renders the pages using simple windows forms controls. Elements like &lt;i&gt;div,b,p&lt;/i&gt; and such are &lt;i&gt;Panels&lt;/i&gt;. Text inside a &lt;i&gt;b&lt;/i&gt; node is a &lt;i&gt;Label inside a Panel&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;This method has one major flaw: text formatting. Take a page which has a really really long text node. How would that be rendered on multiple lines? I could make the label higher... but...&lt;br /&gt;&lt;br /&gt;If the page had something like.. &lt;br /&gt;&amp;lt;i&gt;Hello&amp;lt;/i&gt;, here is a really long sentence which needs to be on multiple lines&lt;br /&gt;&lt;br /&gt;..then we'd be in trouble. This is because we'd first have a small Panel which would containt the text Hello and then &lt;b&gt;another&lt;/b&gt; Panel which would contain the rest of the text.&lt;br /&gt;&lt;br /&gt;&lt;img src="http://students.osao.fi/~b3haja01/boxex1.JPG" /&gt;&lt;br /&gt;Imagine stretching the second box higher there... this is what happens:&lt;br /&gt;&lt;img src="http://students.osao.fi/~b3haja01/boxex2.JPG" /&gt;&lt;br /&gt;So it would be just completely stupid looking. That is caused because the second panel cannot magically extend itself to begin from the left edge on the second row but not on the first.&lt;br /&gt;&lt;br /&gt;So...&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;GDI+ to the rescue&lt;/h3&gt;&lt;br /&gt;To overcome the problem, I will have to trash the current model of rendering pages which has the parts of the page as separate controls. I'd have to do a &lt;i&gt;single über control&lt;/i&gt; which renders the whole page using some kind of magic!&lt;br /&gt;&lt;br /&gt;That magic I'll call GDI+, which are the tools I can use from .NET Framework to render custom controls or whatever I'd want. (or something like that, google for GDI+)&lt;br /&gt;&lt;br /&gt;So... what I'll do is... begin creating a custom super duper über control, which is made of win and good. It's gonna be one hell of a job, but I don't care. As long as I have fun... ;)&lt;br /&gt;&lt;br /&gt;For starters, I have to make it render text. Okay. Then, if I'd want to make the text selectable, I'd have to make a custom routine which would highlight the text... and check where the mouse cursor actually was to determine what text to highlight.&lt;br /&gt;&lt;br /&gt;And it would also need to understand clicks on certain parts of the text, like links.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;After that... images... borders... whatever comes to my mind... craziness ensues.&lt;br /&gt;&lt;br /&gt;Oh well. It's gonna be lots of work and if I'll ever get to the point with my custom control where it will render the page like the browser does now with the windows forms controls... I'll be happy. :]&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;and regarding html parsing...&lt;/h3&gt;&lt;br /&gt;I was originally going to use the .NET Framework built-in System.Xml features to parse documents, but considering nobody knows how to write valid html, or even less valid xhtml, I trashed the idea and wrote my own parser.&lt;br /&gt;&lt;br /&gt;After all, I do want the browser to support documents that aren't 100% valid too. My parser seems quite good (for one written by me), it reads the document, gets element values and attributes and seems efficient. However, I don't have any idea at all if it does the parsing in a manner which is considered efficient by others than me too ;)&lt;br /&gt;&lt;br /&gt;At the moment, it takes HTML data and just starts going through it, one character at a time using a StringReader. When it encounters a &amp;lt; character, it does into "read tag" mode, reading until a &amp;gt; is encountered (or EOF. EOF is always checked)&lt;br /&gt;&lt;br /&gt;After reading the data between &amp;lt; and &amp;gt;, it tries to figure out the element type in question and the attributes of the element (if any). Then it proceeds to see if the element is an element which can contain text or child nodes or not(eg. an img element can not)&lt;br /&gt;&lt;br /&gt;If it can contain child nodes, the newly read element is changed as the parent node to which new nodes are appended to, until a closing tag for the element is encountered.&lt;br /&gt;&lt;br /&gt;Text data is considered to start after a &amp;gt;.. everything that comes after that and is not a &amp;lt; is considered as textual data for the current parent node and is converted into a text node when a &amp;lt; is encountered and appended to the parent.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;That's basically it. Any comments and/or suggestions more than welcome.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Whoah, that was a rather long post. My work is soon over for today and it's time to head home!&lt;br /&gt;&lt;br /&gt;&lt;small&gt;ps. a "Read More..." link might be good&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114346317521934552?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114346317521934552/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114346317521934552' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114346317521934552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114346317521934552'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/developing-web-browser-part-3.html' title='Developing a web browser, part 3'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114341673019835172</id><published>2006-03-27T02:45:00.000+03:00</published><updated>2006-03-27T02:45:30.206+03:00</updated><title type='text'>What is it with the night?</title><content type='html'>Yet again I find myself sitting on the computer, blasting trance from the headphones at late night. I have to wake up around 8 AM and now it's almost 3 AM...&lt;br /&gt;&lt;br /&gt;Oh well. I'll have a cup or two of Pepsi after waking up and head to work half-asleep. Whatever. ;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Maybe I'll write some code to keep me busy 'til it's something like 4... :]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114341673019835172?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114341673019835172/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114341673019835172' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114341673019835172'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114341673019835172'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/what-is-it-with-night.html' title='What is it with the night?'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114337073663508194</id><published>2006-03-26T13:00:00.000+03:00</published><updated>2006-04-03T11:21:55.633+03:00</updated><title type='text'>Windows Live Messenger</title><content type='html'>I got an account to the beta test of Windows Live Messenger &lt;small&gt;(prev. known as Messenger 8.0 beta I think)&lt;/small&gt;&lt;br /&gt;&lt;br /&gt;The new GUI looks pretty neat. I don't like too flashy interfaces, but the interface in WLM is quite nice, with gradient backgrounds and such. The color schemes can also be changed per window basis, which is nice. Nothing too flashy but nice touches.&lt;br /&gt;I was also able to find a button to remove the useless tabs from the left side of the contact list!&lt;br /&gt;&lt;br /&gt;Also there's something called Sharing Folders, something to do with file sharing I think. Haven't tried them yet though, but if I can make some folder on the HDD to be shared with someone on MSN, it would be a quite nice feature.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The contact list doesn't seem to differentiate from offline/online users. Where be the (offline) text? I don't know who's online and who's not!&lt;br /&gt;&lt;br /&gt;...wait a second? Offline Instant Messaging? What's this? I clicked on someone who's offline, and it says it will &lt;i&gt;send the messages to the person the next time he signs in&lt;/i&gt;! Nice... although I still want to know who's offline by looking at the list. You can sort the contacts by their status, but then they aren't grouped anymore, except to Online and Offline groups.&lt;br /&gt;&lt;br /&gt;You can also store your buddies contact info and other info. I don't know if this information travels with you if you log into WLM from another computer though.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="text-decoration: line-through"&gt;and my Winamp's Messenger Now Playing plugin broke up. Damn.&lt;/span&gt;&lt;br /&gt;Update 3rd. Apr. 2006: It actually seems that the fault is in WLM. It displays only the song title, but everyone else with an older version sees it allright.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src="http://students.osao.fi/~b3haja01/WLM1.jpg" alt="Windows Live Messenger main window"/&gt;&lt;br /&gt;No, you don't need to see who's on my list or what my name is ;)&lt;br /&gt;&lt;br /&gt;&lt;img src="http://students.osao.fi/~b3haja01/WLM2.jpg" alt="Windows Live Messenger chat window" /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114337073663508194?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114337073663508194/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114337073663508194' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114337073663508194'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114337073663508194'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/windows-live-messenger.html' title='Windows Live Messenger'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114331476650770765</id><published>2006-03-25T21:17:00.000+02:00</published><updated>2006-03-25T21:26:06.856+02:00</updated><title type='text'>Developing a web browser, part 2</title><content type='html'>This far...&lt;br /&gt;&lt;img src="http://students.osao.fi/~b3haja01/googlefi.JPG" /&gt;&lt;br /&gt;&lt;br /&gt;Google.fi in my browser! &lt;br /&gt;&lt;br /&gt;The layout logic is quite simple at the moment. It just goes through all the nodes in the internal DOM tree in the app and checks if the node is a text node and makes a Label with the text the node has.&lt;br /&gt;&lt;br /&gt;The problem now is how to detect what "styles" to apply to each node. For example, if we have the following HTML code...&lt;br /&gt;&lt;br /&gt;&amp;lt;div&gt;&lt;br /&gt; &amp;lt;b&gt;Hello&amp;lt;/b&gt;&lt;br /&gt; &amp;lt;p&gt;Some &amp;lt;i&gt;text&amp;lt;/i&gt; here&amp;lt/p&gt;&lt;br /&gt;&amp;lt;/div&gt;&lt;br /&gt;&lt;br /&gt;so if the B element had 20px of padding for example, how would the program know to not apply it to the P element anymore. The current way of looping through the nodes inside the document can go through all the child nodes, but it doesn't discriminate different childs in any way.&lt;br /&gt;&lt;br /&gt;I'll probably implement some kind of parent-checking or something weird.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114331476650770765?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114331476650770765/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114331476650770765' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114331476650770765'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114331476650770765'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/developing-web-browser-part-2.html' title='Developing a web browser, part 2'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114325405512907080</id><published>2006-03-25T04:30:00.000+02:00</published><updated>2006-03-25T04:34:15.136+02:00</updated><title type='text'>Suggested reading to get sleepy</title><content type='html'>Can't sleep? Print these and read them in bed...&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.w3.org/DOM/DOMTR.html"&gt;DOM Specifications&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.w3.org/XML/"&gt;XML Specs&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.w3.org/TR/html4/"&gt;HTML 4.01 Specs&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.w3.org/TR/xhtml11/"&gt;XHTML 1.1 Specs&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now I'm gonna go sleeeeeeeeeeeeeeeeeee&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114325405512907080?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114325405512907080/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114325405512907080' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114325405512907080'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114325405512907080'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/suggested-reading-to-get-sleepy.html' title='Suggested reading to get sleepy'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114324462264807406</id><published>2006-03-25T01:48:00.000+02:00</published><updated>2006-03-25T01:57:04.666+02:00</updated><title type='text'>Super Eurobeat 166 previews</title><content type='html'>I just listened to the SEB 166 preview clips at &lt;a href="http://avexnet.jp/item/sebea/disc/product/AVCD-10166.html"&gt;Avex's site&lt;/a&gt;. From the clips I'd say it's going to be a good one again, although Shock Out sounds a bit plain to me, but it could be a sound quality issue in the clip.&lt;br /&gt;&lt;br /&gt;At least there's gonna be one great song for sure... Lupin - Black U.F.O. &lt;br /&gt;I already have a version of the song, so I know it's great ;)&lt;br /&gt;&lt;br /&gt;Dave Rodgers's Ring of Fire could be a hit too, since his latest tracks have been really good.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I can't even think how good SEB 170 is going to be if the quality of the songs stay the same or keep rising...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114324462264807406?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114324462264807406/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114324462264807406' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114324462264807406'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114324462264807406'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/super-eurobeat-166-previews.html' title='Super Eurobeat 166 previews'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114315473346687589</id><published>2006-03-24T00:41:00.000+02:00</published><updated>2006-03-24T00:58:53.476+02:00</updated><title type='text'>Developing a web browser</title><content type='html'>I've been coding a web browser, for fun obviously, since there's really no need for a crap browser made by a random coder ;)&lt;br /&gt;&lt;br /&gt;There have been numerous questions to begin with.. How should I implement things like CSS? DOM? Am I ever going to go that far as in implement CSS support at all?&lt;br /&gt;&lt;br /&gt;I didn't even have an idea how things should be drawn to the screen... Windows Forms? Custom GDI drawing? How?&lt;br /&gt;&lt;br /&gt;I did some research on google and found out that you can redefine the &lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndotnet/html/custlaywinforms.asp"&gt;layout engine&lt;/a&gt; used in Windows Forms. &lt;br /&gt;&lt;br /&gt;So I did that.. created a new control based on the Panel class, which allowed me to change the layout engine used to a custom one. &lt;br /&gt;I made a very simple layout engine, which would take some values and create Labels for every one of them and lay them on the panel.&lt;br /&gt;&lt;br /&gt;I also had made some simple classes to open TCP/IP connections to the server and to send HTTP requests. They're a buggy pile of crap at the moment, I will look at them  (maybe) at the point when I get the actual HTML outputted to the screen in somewhat similar manner as in Lynx &lt;small&gt;(a text-only browser on *nix)&lt;/small&gt;.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For saving the HTML data, I created some basic classes, with somewhat similar features as XmlNode and some ideas borrowed from &lt;a href="http://www.w3.org/DOM/"&gt;W3C's DOM&lt;/a&gt; specification. Basically just something to contain possible text-data which the HTML element had, the attributes of the tag and possible child elements.&lt;br /&gt;&lt;br /&gt;I also made some structures to be used with CSS. I thought that I'd use something like CSS to format the documents to begin with, so it would be easy to add support for it later.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now I'm in the point where the HTML structure is parsed correctly (afaik) and I need to make a new layout engine which loads and displays the site, instead of a list of the tags found in the document like it does now :)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I've had to do lots of thinking. New concepts, new programming models in C# etc.&lt;br /&gt;The last time I've thought this much was when I was coding a 2D engine in C#+Direct3D (abandoned due to lack of intrest at the moment)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Oh well. Maybe it's time to go sleep now. Gotta get up early tomorrow to work and so on.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114315473346687589?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114315473346687589/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114315473346687589' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114315473346687589'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114315473346687589'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/developing-web-browser.html' title='Developing a web browser'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114315301992120775</id><published>2006-03-24T00:28:00.000+02:00</published><updated>2006-03-24T00:30:19.930+02:00</updated><title type='text'>What's wrong with russian drivers?</title><content type='html'>&lt;a href="http://video.google.com/videoplay?docid=3853924320276782507"&gt;http://video.google.com/videoplay?docid=3853924320276782507&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Someone tell me. Are there actually any &lt;i&gt;requirements&lt;/i&gt; for a license in Russia? Or do you even need a license? :]&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114315301992120775?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114315301992120775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114315301992120775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114315301992120775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114315301992120775'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/whats-wrong-with-russian-drivers.html' title='What&apos;s wrong with russian drivers?'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114312895281839660</id><published>2006-03-23T17:05:00.000+02:00</published><updated>2006-03-23T17:53:02.700+02:00</updated><title type='text'>Microsoft calling back on lunches</title><content type='html'>Like I thought. They probably got a huge amount of hits and now the site needs you to register an account, which will probably be validated against a database of MS OEM distributors.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114312895281839660?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114312895281839660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114312895281839660' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114312895281839660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114312895281839660'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/microsoft-calling-back-on-lunches.html' title='Microsoft calling back on lunches'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114310914010785066</id><published>2006-03-23T12:09:00.000+02:00</published><updated>2006-03-23T12:20:33.883+02:00</updated><title type='text'>Microsoft offering McDonalds lunches</title><content type='html'>Microsoft is offering free lunch coupons at McDonalds for finnish users if they answer correctly to a small quiz at their website.&lt;br /&gt;Links and correct answers are spreading like wildfire on IRC, forums, MSN, etc.&lt;br /&gt;&lt;br /&gt;I wonder if Microsoft is going to have thousands and thousands of people answering the questions and getting a free lunch...&lt;br /&gt;&lt;br /&gt;Reminds me of the campaign the finnish distributor of Pepsi had.. They had numbers in the Pepsi bottles which you could enter at their website. With something like 1000 numbers, you'd get a decent laptop.&lt;br /&gt;&lt;br /&gt;What happened was that some people started hoarding Pepsi and Pepsi Max bottles so much, that they even ran out at some stores! The manufacturer hadn't expected this and called back the campaign earlier than they were going to. Probably because they were losing money.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;It was actually possible for you to &lt;b&gt;gain&lt;/b&gt; money by that. You'd buy the bottles, enter the codes and then &lt;i&gt;sell&lt;/i&gt; the bottles cheaper than in stores.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;If anyone from Finland happens to read this, &lt;a href="http://www.oem-menu.fi/"&gt;here's the link to the quiz&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114310914010785066?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114310914010785066/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114310914010785066' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114310914010785066'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114310914010785066'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/microsoft-offering-mcdonalds-lunches.html' title='Microsoft offering McDonalds lunches'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114304711376193925</id><published>2006-03-22T18:59:00.000+02:00</published><updated>2006-03-22T19:05:13.766+02:00</updated><title type='text'>Graphics tablet funnay</title><content type='html'>I borrowed a graphics tablet from a friend/coworker (Thanks!, although I doubt you'll ever read this!)...&lt;br /&gt;&lt;br /&gt;Ever tried playing games with one? Strategy games are fun with it, just tap the tablet with the pen and stuff.&lt;br /&gt;I also tried playing &lt;a href="http://www.dayofdefeat.net/"&gt;Day of Defeat&lt;/a&gt; with it... the damn game doesn't seem to use absolute cursor positioning to track mouse movements, since all I was able to do, was spin around uncontrollably if the pen touched anything but the center of the tablet surface.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Note to self: code your games that use mouse with tablet users in mind. They're fun, although not necessarily useful for gaming ;)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Now I have to do some adjusting on some CSS code... laters.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114304711376193925?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114304711376193925/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114304711376193925' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114304711376193925'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114304711376193925'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/graphics-tablet-funnay.html' title='Graphics tablet funnay'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114302404390075167</id><published>2006-03-22T12:29:00.000+02:00</published><updated>2006-03-22T12:40:43.953+02:00</updated><title type='text'>Opera 9 Tech Preview 2</title><content type='html'>I installed the &lt;a href="http://my.opera.com/community/forums/topic.dml?id=122915"&gt;latest tech preview of the Opera browser&lt;/a&gt;. Lots of new cool and useful features, like built-in BitTorrent support and Widgets.&lt;br /&gt;&lt;br /&gt;Widgets?...&lt;br /&gt;Ever used anything like &lt;a href="http://www.samurize.com"&gt;Samurize&lt;/a&gt;?&lt;br /&gt;Basically they are floating objects programmed with HTML/JavaScript embedded in the browser that do something. Like an analog clock, the latest news, TV shows, the weather, you name it.&lt;br /&gt;&lt;br /&gt;Makes me wish I had two monitors... having the Widgets float on top of everything else forces you to hide them at times. They need to add a feature to force the Widgets to only show up on the desktop.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Another useful new feature is "Create Search"... You might already know, that you can add custom searches to Opera's search dropbox and to the URL search (eg. type "g foo" as the url to search Google for foo)... that feature lacked any inuitive and easy way of adding new searches. &lt;br /&gt;&lt;br /&gt;Now you can just go to the search engine you want, right click on the search field and choose "Create Search". Easy, isn't it?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://labs.opera.com/news/2006/02/07/2/"&gt;Opera 9 Tech Preview 2 changelog&lt;/a&gt;&lt;br /&gt;&lt;a href="http://my.opera.com/community/dev/widgets/"&gt;More about Opera Widgets&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Watch out Firefox, if the word about Opera gets out more, you'll have a tough competitor!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114302404390075167?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114302404390075167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114302404390075167' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114302404390075167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114302404390075167'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/opera-9-tech-preview-2.html' title='Opera 9 Tech Preview 2'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114292270590163676</id><published>2006-03-21T08:14:00.000+02:00</published><updated>2006-03-21T08:31:45.916+02:00</updated><title type='text'>Densha!</title><content type='html'>One of the few japanese tv-series I've watched, Densha Otoko, seems to be almost fully available for watching at &lt;a href="http://www.youtube.com/"&gt;YouTube&lt;/a&gt;. The quality isn't sky-high, but watchable.&lt;br /&gt;&lt;br /&gt;I can't bother babbling about the series here, so if you don't know what it's about &lt;a href="http://wiki.d-addicts.com/Densha_Otoko"&gt;go look here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The episodes&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=d2rwDdwy2fU"&gt;Episode 1&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=5jgGnXsE7tk"&gt;Episode 2&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=mMl1fOOIqmI"&gt;Episode 3&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=tIFwcgenjGs"&gt;Episode 4&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=Ms79Wl9mfCA"&gt;Episode 5&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=CxorcinGMsM"&gt;Episode 6&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=SI8W7sUVEAc"&gt;Episode 7&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Episode 8 not available&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=J3ero3wmP-g"&gt;Episode 9&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=uLUHpOHuz_w"&gt;Episode 10&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.youtube.com/watch?v=dpC66jo4InI"&gt;Episode 11 part 1&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=nbKrwZ6cSyI"&gt;Episode 11 part 2&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;br /&gt;A very fun and touching series in my opinion.&lt;br /&gt;&lt;br /&gt;&lt;small&gt;The missing episode can be easily found with a bit of googling&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114292270590163676?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114292270590163676/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114292270590163676' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114292270590163676'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114292270590163676'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/densha.html' title='Densha!'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114289622888780472</id><published>2006-03-21T01:00:00.000+02:00</published><updated>2006-03-21T01:10:28.896+02:00</updated><title type='text'>Old</title><content type='html'>While trying to figure out something fun to do, I started going through my old files on various servers around the internets.&lt;br /&gt;&lt;br /&gt;Finding old logs... old versions of my site... etc.&lt;br /&gt;&lt;br /&gt;I hate that!&lt;br /&gt;&lt;br /&gt;I hate my old sites!&lt;br /&gt;&lt;br /&gt;I hate how I talked on IRC in the old days!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I always find it quite embarrasing for some reason. I acted rather lame and childish some years back... and I don't like showing the files to anyone, even though they're actually rather funny.&lt;br /&gt;&lt;br /&gt;Oh well. That's how it goes I guess. I tend to show parts of old logs to others, especially if they have something funny about the other person ;)&lt;br /&gt;And it's actually quite fun to look at my old sites, seeing how crap they were... or my old PHP/whatever scripts. &lt;br /&gt;&lt;br /&gt;I actually even found a few useful bits and pieces.. and some things worth backing up too.&lt;br /&gt;&lt;br /&gt;I backed up a huuuge archive of funny pictures, .swf files etc., some old PHP scripts (a POP3 reader, a version of the POP3 reader which uses WML etc.), an old app (HL Script Utility) along the other things.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;I wonder what I'll think of my writings here or somewhere in a couple of years? Who knows what an asshole I might be then!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114289622888780472?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114289622888780472/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114289622888780472' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114289622888780472'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114289622888780472'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/old.html' title='Old'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114287216976632932</id><published>2006-03-20T18:28:00.000+02:00</published><updated>2006-03-20T18:29:29.780+02:00</updated><title type='text'>AMD x2 CPU's - Now with built-in speedhack!</title><content type='html'>A funny thing I heard recently on IRC... AMD's dual-core CPU's supposedly run Counter-Strike too fast :]&lt;br /&gt;&lt;br /&gt;Have no proof though, don't own one of those or anything.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114287216976632932?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114287216976632932/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114287216976632932' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114287216976632932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114287216976632932'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/amd-x2-cpus-now-with-built-in.html' title='AMD x2 CPU&apos;s - Now with built-in speedhack!'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114286520882615123</id><published>2006-03-20T16:22:00.000+02:00</published><updated>2006-03-20T16:33:29.990+02:00</updated><title type='text'>JavaScript/DOM</title><content type='html'>JavaScript is an often disregarded technique to add a new level of user interaction to webpages.&lt;br /&gt;&lt;br /&gt;I used to hate it. Now I love it.&lt;br /&gt;Back in the day, the support for JavaScript was SO different between browsers. Now most browsers support it quite well. &lt;br /&gt;&lt;br /&gt;Well enough to do simple things with ease and more difficult things with... well, with more difficulty.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There also seems to be a huge difference in the performance of the JavaScript "engines" in the browsers. Let's take a script which highlights table cells when you point the cursor over one.&lt;br /&gt;&lt;br /&gt;1. Find the element where the mouse is&lt;br /&gt;2. Loop through the table to find the position of the element in the table&lt;br /&gt;3. Loop through the table to highlight the horizontal and vertical line of cells where the highlighted cell is&lt;br /&gt;4. Highlight the actual cell too&lt;br /&gt;&lt;br /&gt;That works lightning fast in Opera and Firefox. Internet Explorer on the other hand is quite slow.&lt;br /&gt;&lt;br /&gt;I know the code I've written isn't very efficient and it could be faster for IE too. I just haven't had the time to go through the algorithms.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;There's still one very annoying thing even with the modern browsers' quite equal JavaScript support. COLORS!&lt;br /&gt;&lt;br /&gt;Wanna detect a color?&lt;br /&gt;&lt;div style="font-size: 12px"&gt;&lt;br /&gt;if(x.style.backgroundColor != "#ff0000" &amp;&amp; x.style.backgroundColor != "rgb(255, 0, 0)" &amp;&amp; x.style.backgroundColor != "blue") &lt;br /&gt;&lt;/div&gt;&lt;br /&gt;You need 3 different detects.&lt;br /&gt;Shoot me now!&lt;br /&gt;&lt;br /&gt;(note: the colors in the example might not all be blue but you get the point)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114286520882615123?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114286520882615123/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114286520882615123' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114286520882615123'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114286520882615123'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/javascriptdom.html' title='JavaScript/DOM'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24283334.post-114265669876326003</id><published>2006-03-18T06:07:00.000+02:00</published><updated>2006-03-18T06:42:57.266+02:00</updated><title type='text'>Laptop</title><content type='html'>Something I've been tinkering with lately is this old laptop, which I call "craptop"&lt;br /&gt;Why? Well...&lt;br /&gt;&lt;ol&gt;&lt;br /&gt;&lt;li&gt;Broken HDD&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Broken CDD&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Missing battery (probably broken too)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;300mhz/64mb RAM&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;&lt;p&gt;I was thinking about converting the LCD screen to a "normal" monitor. Did a bit searching on the web and it seems possible, although troublesome.&lt;/p&gt;&lt;p&gt;Especially the &lt;a href="http://www.geocities.com/p9019/lcdpanel"&gt;article here&lt;/a&gt; was intresting.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://photos1.blogger.com/blogger/7067/2515/1600/P3201213.jpg"&gt;&lt;img style="FLOAT: left; MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/7067/2515/320/P3201213.jpg" border="0" /&gt;&lt;/a&gt; Earlier today I took off the plastic cover on the LCD monitor.&lt;/p&gt;&lt;p&gt;It was quite easy after a while. I was quite careful to not break anything..&lt;/p&gt;&lt;p&gt;just had to take off the bolt covers with a paperknife since I had nothing better for the task, unscrew the bolts and press from strategic positions in the plastic to clip it off.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://photos1.blogger.com/blogger/7067/2515/1600/P3201214.jpg"&gt;&lt;/a&gt;&lt;a href="http://photos1.blogger.com/blogger/7067/2515/1600/P3201214.0.jpg"&gt;&lt;img style="MARGIN: 0px 10px 10px 0px; CURSOR: hand" alt="" src="http://photos1.blogger.com/blogger/7067/2515/320/P3201214.0.jpg" border="0" /&gt;&lt;/a&gt; &lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;So, the next thing to do is probably to remove the keyboard and the rest of the plasitc covering to get to the wiring... then to think how on earth I will connect the wires to a normal lcd connector...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24283334-114265669876326003?l=zeeohemgee.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://zeeohemgee.blogspot.com/feeds/114265669876326003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24283334&amp;postID=114265669876326003' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114265669876326003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24283334/posts/default/114265669876326003'/><link rel='alternate' type='text/html' href='http://zeeohemgee.blogspot.com/2006/03/laptop.html' title='Laptop'/><author><name>Jani</name><uri>http://www.blogger.com/profile/06586373230409183724</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>
