<?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:blogger='http://schemas.google.com/blogger/2008' 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-7578929742950054449</id><updated>2026-03-29T06:18:35.806+08:00</updated><category term="3d"/><category term="blender"/><category term="tools"/><category term="games"/><category term="DOSRunner"/><category term="Snarl Tray Notifications"/><category term="Windows"/><category term="gsmGPS"/><category term="PocketTweet"/><category term="Twitter"/><category term="Windows 7"/><category term="android"/><category term="chip8"/><category term="emulation"/><category term="funny"/><category term="haiku"/><category term="interesting"/><category term="keylogger"/><category term="pyglet"/><category term="python"/><category term="virtualization"/><title type='text'>moises&#39; blog</title><subtitle type='html'>A blog on programming for Windows, Mac, Linux, and mobile devices. Plus some 3D modeling. And pretty much everything on the Internet.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>27</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-6798176200198717596</id><published>2012-06-30T05:14:00.001+08:00</published><updated>2022-10-15T18:45:24.728+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="chip8"/><category scheme="http://www.blogger.com/atom/ns#" term="emulation"/><category scheme="http://www.blogger.com/atom/ns#" term="pyglet"/><category scheme="http://www.blogger.com/atom/ns#" term="python"/><title type='text'>Emulation Basics: Write your own Chip 8 Emulator/Interpreter</title><content type='html'>It has been quite a while since I last posted here; I&#39;ve been keeping myself busy with work and developing stuff for the iOS. I bought a developer ID 2 years ago (for both iOS and Macs), and promised myself that I will create apps for both platforms at least twice a year, just to get back what I spent.&lt;br /&gt;
&lt;br /&gt;
So anyway, I recently got my &lt;a href=&quot;http://www.raspberrypi.org/&quot;&gt;Raspberry Pi&lt;/a&gt; from the mail, and was looking at things to do with it. The first thing that came to mind was to PLAY GAMES OBVIOUSLY, but the little thing is ARM-based, and not many emulators are built to maximize its powerful GPU.&lt;br /&gt;
&lt;br /&gt;
That got me into thinking - what if I wrote my own emulators for it? A ~700Mhz processor is reasonably fast, and the experience may teach me a lot of things. Plus, the thing comes with Python. Who doesn&#39;t love Python? The less I think about code boilerplate, the more I get done.&lt;br /&gt;
&lt;br /&gt;
So let&#39;s get started.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;img src=&quot;http://i.imgur.com/A5KeV.png&quot; /&gt;&lt;br /&gt;
&lt;b&gt;&lt;u&gt;The CPU: CHIP8&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
To get started with emulation, let&#39;s start small. Oh let&#39;s say a theoretical machine. With less than 50 instructions (if we did the Gameboy, which is based on a Z80, that would be ~250 instructions, and is a bit too much for a blog article. Or maybe I&#39;m just lazy).&lt;br /&gt;
&lt;br /&gt;
AHA! One machine actually fits this bill - &lt;a href=&quot;http://en.wikipedia.org/wiki/CHIP-8&quot; style=&quot;font-weight: bold;&quot;&gt;CHIP8&lt;/a&gt;. CHIP8 isn&#39;t really a machine in the physical sense - it is actually an interpreter, which runs its programs in a virtual machine. It was developed by the late Joseph Weisbecker. It first appeared in graphing calculators - and was the reason for the drop in their productivity due to playing too much PONG.&lt;br /&gt;
&lt;br /&gt;
The first step in emulation is trying to understand the innards of the hardware. Luckily for us, CHIP8 is pretty well documented - my favorite is &lt;a href=&quot;http://devernay.free.fr/hacks/chip8/C8TECH10.HTM#0.0&quot;&gt;Cogwood&#39;s CHIP-8 technical reference&lt;/a&gt;. It even includes the extension SuperChip instructions. &lt;a href=&quot;http://en.wikipedia.org/wiki/CHIP-8&quot;&gt;Wikipedia&lt;/a&gt; is also a great resource for this - their opcode descriptions are actually the ones I first used before I discovered Cogwood&#39;s article.&lt;br /&gt;
&lt;br /&gt;
So let us begin. First, understand the hardware. Basically, all machines are made up of 3 parts (at least for me :)):&lt;br /&gt;
&lt;br /&gt;
1. Input&lt;br /&gt;
2. Output&lt;br /&gt;
3. CPU&lt;br /&gt;
4. Memory&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Inputs&lt;/b&gt;&lt;br /&gt;
For the CHIP8 virtual machine, the input comes from a 16-button keyboard (pretty convenient that the number of keys falls within a nibble). The machine is also fed with the programs it is supposed to run.&lt;br /&gt;
In python, we just need to store key input states and check these per cycle:&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; self.key_inputs = [0]*16&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Output&lt;/b&gt;&lt;br /&gt;
For output, the machine uses a 64x32 display, and a simple sound buzzer. The display is basically just an array of pixels that are either in the on or off state:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; self.display_buffer = [0]*32*64 # 64*32&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;CPU and Memory&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
Now for the &quot;hard&quot; part. The Chip 8 CPU has several parts of note, and all are important to understand how it works. I&#39;ll run through them here, but for more info see the Cogwood reference I linked to earlier.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Memory&lt;/b&gt;&lt;br /&gt;
CHIP8 has memory that can hold up to 4096 bytes. This includes the interpreter itself, the fonts (more on this later), and where it loads the program it is supposed to run (from input). In python, this will be:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; self.memory = [0]*4096 # max 4096&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;Registers&lt;/b&gt;&lt;br /&gt;
The CHIP8 has 16 8-bit registers (usually referred to as Vx where x is the register number in Cogwood&#39;s reference). These are generally used to store values for operations. The last register, Vf, is mostly used for flags and should be avoided for use in programs. In python, we will be storing our register values as:&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; self.gpio = [0]*16 # 16 zeroes&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
It also has 2 timer registers, that basically just cause delays by decrementing to 0 for each cycle, wasting an operation in the process. Again, in python, this will be as simple as defining two variables that we&#39;ll decrement per cycle.&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; self.sound_timer = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; self.delay_timer = 0&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
It has an index register which is 16-bit.&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; self.index = 0&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
The program counter is also 16-bit.&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; self.pc = 0&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
There is also a stack pointer, which includes the address of the topmost stack element. The stack has at most 16 elements in it at any given time. Since we&#39;re doing this in python, which has a list that we can just pop/append to, we can ignore this. In python, just make a list:&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; self.stack = []&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;On to the code!&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;b&gt;&lt;br /&gt;&lt;/b&gt;&lt;br /&gt;
For our input/output, we are going to use &lt;a href=&quot;http://www.pyglet.org/&quot;&gt;pyglet&lt;/a&gt;, a module for python that wraps around OpenGL boilerplate so we can easily output graphics. It can also handle sound output. And oh, it does keyboard handling too! Now all that&#39;s left is the CPU.&lt;br /&gt;
&lt;br /&gt;
A little notes on my implementation. Since we are using pyglet on Python 2.6, and since pyglet doesn&#39;t work with threads, basically what we&#39;re gonna do is subclass pyglet&#39;s Window class and run our CHIP8 interpreter from there:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; class cpu (pyglet.window.Window)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;The added benefit is we won&#39;t have to make our own input handlers - we just need to override the keyboard input methods:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def on_key_press(self, symbol, modifiers):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def on_key_release(self, symbol, modifiers):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Basically all emulators have a main loop structure like this:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def main(self):&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.initialize()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.load_rom(sys.argv[1])&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; while not self.has_exit:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.dispatch_events() &amp;nbsp; &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.cycle()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.draw()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Let&#39;s go into this code a bit. The first step is to initialize our variables. Set all registers to zero, reset all key inputs to zero and reset the program counter (&lt;/span&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;self.pc&lt;/span&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;). Load a rom, then perform each cycle, updating the display as needed.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;A program counter??? What is this madness? Well basically, a program counter is a pointer to the address in memory of an instruction that we are about to process next. In CHIP8, since the interpreter occupies the first portion of memory, we need to point this to the offset, which is equal to 0x200 (See Cogwood&#39;s reference; we&#39;ll be doing it a lot). Most of these is done in the cycle() method, which we&#39;ll delve into later.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;BUT WAIT! Didn&#39;t I say the fonts were gonna be stored in memory as well? Why yes, and maybe if you stopped interrupting me, my imaginary friend, I would have got to that. Basically CHIP8 uses &quot;sprites&quot; for graphics. Sprites are basically a set of bits that indicate a corresponding set of pixel&#39;s on/off state. For example, a sprite of the number zero would look like this (taken from Cogwood&#39;s reference, the excellent resource):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;table border=&quot;1&quot; cellpadding=&quot;3&quot; cellspacing=&quot;0&quot; style=&quot;font-family: monospace; text-align: center;&quot;&gt;&lt;tbody&gt;
&lt;tr&gt;&lt;td style=&quot;text-align: center;&quot;&gt;&quot;0&quot;&lt;/td&gt;&lt;td style=&quot;text-align: center;&quot;&gt;Binary&lt;/td&gt;&lt;td style=&quot;text-align: center;&quot;&gt;Hex&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;****&lt;/span&gt;&lt;/div&gt;
&lt;tt&gt;&lt;/tt&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;tt&gt;&lt;span style=&quot;background-color: white;&quot;&gt;*&amp;nbsp;&amp;nbsp;*&lt;/span&gt;&lt;/tt&gt;&lt;/div&gt;
&lt;tt&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;*&amp;nbsp;&amp;nbsp;*&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;*&amp;nbsp;&amp;nbsp;*&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;****&lt;/span&gt;&lt;/div&gt;
&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;11110000&lt;/span&gt;&lt;/div&gt;
&lt;tt&gt;&lt;/tt&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;tt&gt;&lt;span style=&quot;background-color: white;&quot;&gt;10010000&lt;/span&gt;&lt;/tt&gt;&lt;/div&gt;
&lt;tt&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;10010000&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;10010000&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;11110000&lt;/span&gt;&lt;/div&gt;
&lt;/tt&gt;&lt;/td&gt;&lt;td&gt;&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;0xF0&lt;/span&gt;&lt;/div&gt;
&lt;tt&gt;&lt;/tt&gt;&lt;br /&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;tt&gt;&lt;span style=&quot;background-color: white;&quot;&gt;0x90&lt;/span&gt;&lt;/tt&gt;&lt;/div&gt;
&lt;tt&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;0x90&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;0x90&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;0xF0&lt;/span&gt;&lt;/div&gt;
&lt;/tt&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Now, CHIP8 (at least the original implementation) has sprites in memory for the 16 hexadecimal digits. Since each font character is 8x5 bits, we&#39;ll need 5 bytes of memory per character. So our init function will now look like this, with font loading included:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def initialize(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.clear()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.memory = [0]*4096 # max 4096&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.gpio = [0]*16 # max 16&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.display_buffer = [0]*64*32 # 64*32&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.stack = []&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.key_inputs = [0]*16 &amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.opcode = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.index = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.delay_timer = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.sound_timer = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.should_draw = False&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.pc = 0x200&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; i = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; while i &amp;lt; 80:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; # load 80-char font set&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.memory[i] = self.fonts[i]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; i += 1&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;I put in a should_draw flag in there so we only update the display when needed. Also, self.clear() just clears the pyglet window.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;With this knowledge, now we can start loading our ROM into memory. ROMs can be read into memory simply by opening them as a binary:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def load_rom(self, rom_path):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Loading %s...&quot; % rom_path)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; binary = open(rom_path, &quot;rb&quot;).read()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; i = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; while i &amp;lt; len(binary):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.memory[i+0x200] = ord(binary[i])&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; i += 1&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp;BTW, the log() function I just put in there so the user has an option to turn on/off log messages when running.&lt;br /&gt;
&lt;br /&gt;
Now to start processing!&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;u&gt;The cycle()&lt;/u&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Each cycle does this:&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def cycle(self):&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.opcode = self.memory[self.pc]&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; #&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; # TODO: process this opcode here&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; #&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; # After&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.pc += 2&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; # decrement timers&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if self.delay_timer &amp;gt; 0:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.delay_timer -= 1&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if self.sound_timer &amp;gt; 0:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.sound_timer -= 1&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; if self.sound_timer == 0:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # Play a sound here with pyglet!&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;An opcode is basically the instruction we need to perform. So at its heart, we are just basically reading the binary, line by line, and performing associated actions per line (this is actually pretty slow - CHIP8 is simple so we won&#39;t notice it, but for other emulated machines, other approaches are possible, which is beyond the scope of this article). Now let&#39;s think about the TODO for a bit.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Each opcode in CHIP8 is 2 bytes long. The program counter points to the current opcode we need to process; after getting the op and processing it, the program counter increments by 2 bytes. Then the process repeats until the program ends.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Here is the tricky part. In C, we could easily just create a switch statement for the opcodes to perform what we want. But we&#39;re using python. Pythont doesn&#39;t have a switch statement - we&#39;d have to go through a compound if-else. Since CHIP8 is pretty simple, we actually can do this, but it will be pretty ugly code, we don&#39;t want this. Luckily, in python, we can use dictionaries to store opcode-method pairs. So the TODO part will simply be like this:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.vx = (self.opcode &amp;amp; 0x0f00) &amp;gt;&amp;gt; 8&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.vy = (self.opcode &amp;amp; 0x00f0) &amp;gt;&amp;gt; 4&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.pc += 2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; # 2. check ops, lookup and execute&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; extracted_op = self.opcode &amp;amp; 0xf000&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; try:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.funcmap[extracted_op]() # call the associated method&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; except:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; print &quot;Unknown instruction: %X&quot; % self.opcode&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;A little info on CHIP8 opcodes. They are usually in the format XXXX. Usually, you can already decipher the instruction from its first (leftmost) nibble, so we extract the op with a bitwise AND, and look it up in our function map (self.funcmap). If it isn&#39;t there, then we will just raise an error. NOTE: self.pc is incremented BEFORE cycle(), so any modifications to it (e.g. in jumps) are retained.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;There! we already have the basic skeleton to our emulator. Now we just have to implement all of the instructions one-by-one. (the &quot;fun&quot;part).&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;b&gt;&lt;u&gt;Sample instruction: Clear a screen with 00E0 and return with 00EE&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Cogwood&#39;s excellent reference lists all the necessary instructions in the previously linked document. Here, we will implement the first and simplest one - the instruction to clear the screen. This corresponds to the opcode 0x00E0. But wait; since at our cycle() we just used the leftmost nibble, there is a possibility that we might conflict with another instruction that falls in the 0x0XXX format: 0x00EE, or the &quot;return from subroutine&quot; opcode. So what we can do is to do another extraction:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _0ZZZ(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; extracted_op = self.opcode &amp;amp; 0xf0ff&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; try:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.funcmap[extracted_op]()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; except:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; print &quot;Unknown instruction: %X&quot; % self.opcode&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Here, when we encounter an opcode which has 0 as the leftmost nibble, we extract the first and last 2 nibbles and look the associated method in the function map. 0x00E0 should map to CLS, and 0x00EE should map to the return subroutine:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _0ZZ0(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Clears the screen&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.display_buffer = [0]*64*32 # 64*32&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.should_draw = True&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;To return from a subroutine, we just need to pop the topmost address from our stack:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _0ZZE(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Returns from subroutine&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.pc = self.stack.pop()&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;And in self.funcmap:&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.funcmap = {0x0000: self._0ZZZ,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x00e0: self._0ZZ0,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x00ee: self._0ZZE,&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; ....&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;where self._0ZZE will be the &quot;return&quot; method. Why don&#39;t we just set 0x00E0 and 0x00EE to the methods needed? Well, we actually could have, but the 0x0xxx instructions are actually special cases, as they don&#39;t have inputs. Usually the last three nibbles contain inputs to the operation, and aren&#39;t constant, so they can&#39;t be mapped as is. For example, let&#39;s look at the next instruction, which performs a JUMP:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;b&gt;&lt;u&gt;Sample instruction: JUMPing with 1XXX&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;The JUMP opcode, which starts with 1, is followed by three nibbles corresponding to the address of the instruction to be executed next. Now you see why we needed to extract nibbles bit-wise - the jump address changes, but the opcode identifier doesn&#39;t, and we can use that to identify the instruction.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;To perform a jump, simply set the program counter to the address of the next instruction, so it will be performed in the next cycle:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _1ZZZ(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Jumps to address NNN.&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.pc = self.opcode &amp;amp; 0x0fff&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;And in our function map:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;&quot;&gt;
&amp;nbsp; &amp;nbsp; self.funcmap = {0x0000: self._0ZZZ,&lt;/div&gt;
&lt;div style=&quot;font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x00e0: self._0ZZ0,&lt;/div&gt;
&lt;div style=&quot;font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x00ee: self._0ZZE,&lt;/div&gt;
&lt;div style=&quot;font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;&quot;&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 0x1000: self._1ZZZ,&lt;/div&gt;
&lt;div style=&quot;font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;&quot;&gt;
&amp;nbsp; &amp;nbsp; ....&lt;/div&gt;
&lt;div style=&quot;font-family: &amp;quot;Courier New&amp;quot;, Courier, monospace;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;That&#39;s it! Now, rinse and repeat for each of the opcodes defined in the instruction set, and voila! Your very own CHIP8 emulator.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;b&gt;&lt;u&gt;Notes on the important opcodes:&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;b&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;b&gt;Opcodes using the registers V0 to VF:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Note on my cycle() implementation. You will notice these two lines:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.vx = (self.opcode &amp;amp; 0x0f00) &amp;gt;&amp;gt; 8&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.vy = (self.opcode &amp;amp; 0x00f0) &amp;gt;&amp;gt; 4&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;u&gt;&lt;br /&gt;&lt;/u&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Some opcodes use the general purpose registers. For example, &amp;nbsp;0x4XNN, which&amp;nbsp;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&quot;Skips the next instruction if VX doesn&#39;t equal NN&quot;. To handle this, the above instructions just extract the nibbles with bitwise operations to get the associated registers (which are usually stored in the 2nd and third nibbles). Then, I can use this to perform the skip:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _4ZZZ(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Skips the next instruction if VX doesn&#39;t equal NN.&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if self.gpio[self.vx] != (self.opcode &amp;amp; 0x00ff):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.pc += 2&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;The same goes for comparing:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _5ZZZ(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Skips the next instruction if VX equals VY.&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if self.gpio[self.vx] == self.gpio[self.vy]:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.pc += 2&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;b&gt;Using the carry flag&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;You have to be careful in reading the Cogwood reference, as some operations require setting the VF flag. For example, operation 0x8XX4 uses VF as a carry flag in addition. Why is this needed? Remember when we said that the registers only store 8-bit values? If we add 2 8-bit values, there is a possibility that the result will overflow (1 byte has a maximum value of just 0xFF). If the result is greater than the maximum, the carry flag is set.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _8ZZ4(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Adds VY to VX. VF is set to 1 when there&#39;s a carry, and to 0 when there isn&#39;t.&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if self.gpio[self.vx] + self.gpio[self.vy] &amp;gt; 0xff:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.gpio[0xf] = 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; else:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.gpio[0xf] = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.gpio[self.vx] += self.gpio[self.vy]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.gpio[self.vx] &amp;amp;= 0xff&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;It is also used in subtraction as a &quot;borrow&quot; flag:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _8ZZ5(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;VY is subtracted from VX. VF is set to 0 when there&#39;s a borrow, and 1 when there isn&#39;t&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if self.gpio[self.vy] &amp;gt; self.gpio[self.vx]:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.gpio[0xf] = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; else:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.gpio[0xf] = 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.gpio[self.vx] = self.gpio[self.vx] - self.gpio[self.vy]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.gpio[self.vx] &amp;amp;= 0xff&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;b&gt;Drawing:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;b&gt;Now for the most difficult part.&lt;/b&gt;&amp;nbsp;Well, actually not really. Drawing is pretty straightforward in the CHIP8. A pixel is either on or off, and we store the states in the display_buffer we defined earlier. There are two op codes that do drawing: 0x&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;DXXX, which draws sprites loaded from the ROM, and 0x&lt;/span&gt;&lt;/span&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;FZ29, which just draws a character. Let&#39;s implement the simpler one first; drawing a character.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _FZ29(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Set index to point to a character&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.index = (5*(self.gpio[self.vx])) &amp;amp; 0xfff&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Yup, that&#39;s it. This op just sets the index register to the address of the first byte of the corresponding character. This is because the main drawing code, which we will now implement, uses this register to find the sprite it needs to draw. To understand this better, let&#39;s read the documentation again. DXYN means, according to Cogwood:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: monospace;&quot;&gt;Display&amp;nbsp;&lt;/span&gt;&lt;em style=&quot;font-family: monospace;&quot;&gt;n&lt;/em&gt;&lt;span style=&quot;font-family: monospace;&quot;&gt;-byte sprite starting at memory location I at (V&lt;/span&gt;&lt;em style=&quot;font-family: monospace;&quot;&gt;x&lt;/em&gt;&lt;span style=&quot;font-family: monospace;&quot;&gt;, V&lt;/span&gt;&lt;em style=&quot;font-family: monospace;&quot;&gt;y&lt;/em&gt;&lt;span style=&quot;font-family: monospace;&quot;&gt;), set VF = collision.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Remember our discussion on font sprites earlier? It applies to custom sprites too. Each row (byte) corresponds to an 8-pixel row on the screen. But here, instead of being a fixed 5 bytes, the N value can correspond to a custom sprite height. Also, the bytes are XOR&#39;ed onto the screen. This is actually ingenious - since CHIP8 resources are limited, it used the actual display to store sprite states! So XOR&#39;ing a pixel to the new value will tell you if the state changed, and therefore indicate a collision. Here, a collision is flagged in VF: if a pixel changes from 1 to 0, then VF is set to 1. Now to implement the buffer update code:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _DZZZ(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Draw a sprite&quot;)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;span style=&quot;background-color: white;&quot;&gt;&amp;nbsp; &amp;nbsp; self.gpio[0xf] = 0&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; x = self.gpio[self.vx] &amp;amp; 0xff&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; y = self.gpio[self.vy] &amp;amp; 0xff&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; height = self.opcode &amp;amp; 0x000f&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; row = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; while row &amp;lt; height:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; curr_row = self.memory[row + self.index]&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; pixel_offset = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; while pixel_offset &amp;lt; 8:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; loc = x + pixel_offset + ((y + row) * 64)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; pixel_offset += 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if (y + row) &amp;gt;= 32 or (x + pixel_offset - 1) &amp;gt;= 64:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # ignore pixels outside the screen&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; continue&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; mask = 1 &amp;lt;&amp;lt; 8-pixel_offset&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; curr_pixel = (curr_row &amp;amp; mask) &amp;gt;&amp;gt; (8-pixel_offset)&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; self.display_buffer[loc] ^= curr_pixel&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if self.display_buffer[loc] == 0:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; self.gpio[0xf] = 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; else:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; self.gpio[0xf] = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; row += 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; self.should_draw = True&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white;&quot;&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;What are we doing here? Basically we are going to the pixel indicated at x,y - then we compare each pixel in our sprite to that in our buffer, and XOR as needed. Then, we just set our draw flag to True, so our draw() call catches it.&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Some noted on our draw() method. I used pyglet, which is a wrapper to OpenGL, but it is really slow with low level stuff, like doing pixelwise drawing. So here, I am actually drawing it pseudo-pixelwise - I have a 10x10 pixel (which makes my window 640x320), and I draw the pixel at x*10 and y*10:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def draw(self):&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if self.should_draw:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; # draw&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.clear()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; line_counter = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; i = 0&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; while i &amp;lt; 2048:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; if self.display_buffer[i] == 1:&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; # draw a square pixel&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; self.pixel.blit((i%64)*10, 310 - ((i/64)*10))&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; i += 1&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.flip()&lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.should_draw = False&lt;/span&gt;&lt;br /&gt;
&lt;div style=&quot;font-family: Times, &amp;quot;Times New Roman&amp;quot;, serif;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Times, &amp;quot;Times New Roman&amp;quot;, serif;&quot;&gt;
This will be slow for other applications, but is fast enough for the purposes of our demonstration.&lt;/div&gt;
&lt;div style=&quot;font-family: Times, &amp;quot;Times New Roman&amp;quot;, serif;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Times, &amp;quot;Times New Roman&amp;quot;, serif;&quot;&gt;
&lt;b&gt;Keyboard input&lt;/b&gt;&lt;/div&gt;
&lt;div style=&quot;font-family: Times, &amp;quot;Times New Roman&amp;quot;, serif;&quot;&gt;
Since we subclassed pyglet&#39;s Window, we can just override the keyboard input methods:&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def on_key_press(self, symbol, modifiers):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Key pressed: %r&quot; % symbol)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if symbol in KEY_MAP.keys():&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.key_inputs[KEY_MAP[symbol]] = 1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; if self.key_wait:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; self.key_wait = False&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; else:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; super(cpu, self).on_key_press(symbol, modifiers)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def on_key_release(self, symbol, modifiers):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Key released: %r&quot; % symbol)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if symbol in KEY_MAP.keys():&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.key_inputs[KEY_MAP[symbol]] = 0&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;The code above is pretty self explanatory - we are just updating the key states as inputted in the keyboard. In the emulator, we can just read the values as necessary. Input with the keyboard is handled by 0xExxE and 0xExx1:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _EZZE(self):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Skips the next instruction if the key stored in VX is pressed.&quot;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; key = self.gpio[self.vx] &amp;amp; 0xf&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if self.key_inputs[key] == 1:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.pc += 2&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;&amp;nbsp;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; def _EZZ1(self):&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; log(&quot;Skips the next instruction if the key stored in VX isn&#39;t pressed.&quot;)&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; key = self.gpio[self.vx] &amp;amp; 0xf&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; if self.key_inputs[key] == 0:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; self.pc += 2&lt;/span&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;BCD: FX33&lt;/span&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;This instruction is where most people encounter a problem, and I will leave it as an exercise to the reader. But basically, you just need to store the value in VX as a BCD of three digits, starting with memory[self.index] as the most significant digit, to memory[self.index+2] as the least significant digit. So for example, if:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;self.gpio[self.vx] = 123&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;then:&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;self.memory[self.index] = 1&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;self.memory[self.index+1] = 2&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;self.memory[self.index+2] = 3&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;b&gt;&lt;u&gt;&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;Finally, done!&lt;/span&gt;&lt;/u&gt;&lt;/b&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;And that is the bulk of it! Implementing the other instructions should be pretty straightforward. As always, just refer to documentation if in doubt, and always be testing. Cogwood&#39;s reference is an excellent resource; bookmark it for your own good. For testing, you can always download public domain CHIP8 ROMs from the internet (a simple Google will give you a wealth of links). Also, the &lt;a href=&quot;https://github.com/maranas/pyChip8Emu&quot;&gt;source code for the (partially) completed emulator is on github, download it from there!&lt;/a&gt;&amp;nbsp;I say partially, because I haven&#39;t implemented the SuperChip instructions yet - maybe you can do that and give me a pull request? It works with PONG and PONG2 though, which is all that matters to me.&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;That&#39;s it for this (LONG) article. I haven&#39;t written anything in a while, so forgive me for this. Enjoy, and have fun playing PONG!&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;div&gt;
&lt;span style=&quot;font-family: Times, &#39;Times New Roman&#39;, serif;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/6798176200198717596/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2012/06/emulation-basics-write-your-own-chip-8.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/6798176200198717596'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/6798176200198717596'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2012/06/emulation-basics-write-your-own-chip-8.html' title='Emulation Basics: Write your own Chip 8 Emulator/Interpreter'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-7120529177921344924</id><published>2010-11-12T00:23:00.001+08:00</published><updated>2010-11-12T00:24:28.421+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DOSRunner"/><title type='text'>DOSRunner on googlecode</title><content type='html'>Created a repository in Google Code for DOSRunner today. (&lt;a href=&quot;http://code.google.com/p/dosrunner/&quot;&gt;http://code.google.com/p/dosrunner&lt;/a&gt;) It&#39;s under the MIT license, so if anyone finds it useful.</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/7120529177921344924/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/11/dosrunner-on-googlecode.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/7120529177921344924'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/7120529177921344924'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/11/dosrunner-on-googlecode.html' title='DOSRunner on googlecode'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-8501996426953641167</id><published>2010-09-29T22:56:00.004+08:00</published><updated>2010-10-01T02:24:15.120+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="gsmGPS"/><title type='text'>why everyone should use project hosting services</title><content type='html'>... even for open source projects. I have a new PC at home, which is awesome, but someone thought reformatting the older PC&#39;s hard-drive was a good idea.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Sad to say, but &lt;a href=&quot;http://omokute.blogspot.com/2009/04/gsmgps.html&quot;&gt;gsmGPS&lt;/a&gt; is now dead. Not because I&#39;ve grown tired of it, but because I&#39;ve lost all of the sources.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;All my other projects are still alive, though. Thank &lt;a href=&quot;http://code.google.com/hosting/&quot;&gt;Google Code&lt;/a&gt; for that.&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/8501996426953641167/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/09/why-everyone-should-use-project-hosting.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/8501996426953641167'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/8501996426953641167'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/09/why-everyone-should-use-project-hosting.html' title='why everyone should use project hosting services'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-3244163554132808215</id><published>2010-08-09T10:08:00.005+08:00</published><updated>2010-08-09T10:14:14.576+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Snarl Tray Notifications"/><category scheme="http://www.blogger.com/atom/ns#" term="tools"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>snarltraynotifications: code to bypass the default balloon</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5FcVENApjR4HiKQcpvJOyrhluLuCxH7VHW_5u_IdVnqrMBd3o0Rdx3IJ9X9wAg2mRuKZ-NcQRCBCAshkbURbwOeNxGDugbUTXXHDdkuvd7ypuRMA-qMXEzLmzxQ0euk9U25FiCNK4y7qF/s1600/snarl_2.png&quot;&gt;&lt;img style=&quot;display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 281px; height: 108px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5FcVENApjR4HiKQcpvJOyrhluLuCxH7VHW_5u_IdVnqrMBd3o0Rdx3IJ9X9wAg2mRuKZ-NcQRCBCAshkbURbwOeNxGDugbUTXXHDdkuvd7ypuRMA-qMXEzLmzxQ0euk9U25FiCNK4y7qF/s320/snarl_2.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5503226974377621474&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Did a few updates to &lt;a href=&quot;http://code.google.com/p/snarltraynotifications&quot;&gt;Snarl Tray Notifications&lt;/a&gt; (see the &lt;a href=&quot;http://code.google.com/p/snarltraynotifications&quot;&gt;project page&lt;/a&gt;) - the app now hides the original message; only the Snarl notification is visible. It&#39;s usable now, except for messages requiring interaction with the mouse.&lt;br /&gt;&lt;br /&gt;You may also notice, it has an icon now. Thanks to &lt;a href=&quot;http://sekkyumu.deviantart.com&quot;&gt;Sekkyumu&lt;/a&gt; at deviantart. The icon display code is temporary, as I plan on grabbing the original icon from the original message, so we&#39;ll see what happens.&lt;br /&gt;&lt;br /&gt;Until the next update!</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/3244163554132808215/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/08/snarltraynotifications-code-to-bypass.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3244163554132808215'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3244163554132808215'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/08/snarltraynotifications-code-to-bypass.html' title='snarltraynotifications: code to bypass the default balloon'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5FcVENApjR4HiKQcpvJOyrhluLuCxH7VHW_5u_IdVnqrMBd3o0Rdx3IJ9X9wAg2mRuKZ-NcQRCBCAshkbURbwOeNxGDugbUTXXHDdkuvd7ypuRMA-qMXEzLmzxQ0euk9U25FiCNK4y7qF/s72-c/snarl_2.png" height="72" width="72"/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-1122840657643551690</id><published>2010-08-08T09:33:00.005+08:00</published><updated>2010-08-08T11:13:46.015+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Snarl Tray Notifications"/><category scheme="http://www.blogger.com/atom/ns#" term="tools"/><category scheme="http://www.blogger.com/atom/ns#" term="Windows"/><title type='text'>Snarl Tray Notifications</title><content type='html'>I mentioned &lt;a href=&quot;http://www.fullphat.net/index.php&quot;&gt;Snarl&lt;/a&gt; being a notification system option when I wrote about setting up SSBs in Windows. Windows notifications are bearable at best, displayed only with text, and a pale yellow balloon background. My frustration also stems from the fact that I code for both Mac and Windows, and although aesthetically I like Mac and Growl, I must admit that I still go back to Windows (Bootcamped in an MBP) due to its usability.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To solve the notification problem, I hacked up a companion app to Snarl, &lt;a href=&quot;http://code.google.com/p/snarltraynotifications/&quot;&gt;Snarl Tray Notifications&lt;/a&gt;. What it basically does is grab the text from system notifications and push them to Snarl. It would be a lot better if I turned off the default balloons, but this will have to do for now. 4 straight hours of poring through the Win32 API are starting to hurt my eyes.&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To follow the project&#39;s progress and download the latest builds, visit the project&#39;s Google Code site: &lt;a href=&quot;http://code.google.com/p/snarltraynotifications/&quot;&gt;http://code.google.com/p/snarltraynotifications/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Here&#39;s a screen capture of a Windows notification captured and passed to Snarl:&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKeHJCzU46i3BMfAgq-hnlmyef5uIL131gxyKURYWdggghog1MUEfDh4XfR4Me_uUh_nFIfXUU2yNGiT94cDMPvMDH74kVXl3C6J4Lg8oreglxme2aU6-sClINM1WR9cQbSpMwiEldoUM-/s1600/snarl_4.png&quot;&gt;&lt;img style=&quot;display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 270px; height: 100px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKeHJCzU46i3BMfAgq-hnlmyef5uIL131gxyKURYWdggghog1MUEfDh4XfR4Me_uUh_nFIfXUU2yNGiT94cDMPvMDH74kVXl3C6J4Lg8oreglxme2aU6-sClINM1WR9cQbSpMwiEldoUM-/s320/snarl_4.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5502870325196607122&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;I&#39;m still working on how to grab the original message&#39;s icon and message title, but it&#39;s looking a lot better now. Even better, you can download additional &lt;a href=&quot;http://www.fullphat.net/styles/index.html&quot;&gt;Snarl styles&lt;/a&gt; and choose whichever suits your taste.&lt;br /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/1122840657643551690/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/08/snarl-tray-notifications.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/1122840657643551690'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/1122840657643551690'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/08/snarl-tray-notifications.html' title='Snarl Tray Notifications'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKeHJCzU46i3BMfAgq-hnlmyef5uIL131gxyKURYWdggghog1MUEfDh4XfR4Me_uUh_nFIfXUU2yNGiT94cDMPvMDH74kVXl3C6J4Lg8oreglxme2aU6-sClINM1WR9cQbSpMwiEldoUM-/s72-c/snarl_4.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-3111975126611193791</id><published>2010-04-02T05:26:00.006+08:00</published><updated>2010-04-02T05:41:07.841+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="DOSRunner"/><category scheme="http://www.blogger.com/atom/ns#" term="tools"/><title type='text'>DOSRunner</title><content type='html'>&lt;span style=&quot;font-weight: bold;&quot;&gt;DOSRunner&lt;/span&gt; is a Windows shell extension that allows you to run a DOS program easily with &lt;a href=&quot;http://www.dosbox.com/&quot;&gt;DOSBox&lt;/a&gt;, without having to do with DOS commands. Just right click the executable, select &quot;Run in DOSBox&quot;, and play away.&lt;br /&gt;&lt;br /&gt;It works with any version of Windows (from XP to Win7, 32/64 bit), as long as you have a version of &lt;a href=&quot;http://www.dosbox.com/&quot;&gt;DOSBox&lt;/a&gt; installed. (See their &lt;a href=&quot;http://www.dosbox.com/&quot;&gt;website&lt;/a&gt; for downloads).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Download:&lt;/span&gt;&lt;br /&gt;Setup file: &lt;a href=&quot;http://www.mediafire.com/?yxyvu2oyzmm&quot;&gt;Download here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Requirements:&lt;/span&gt;&lt;br /&gt;- Any version of DOSBox&lt;br /&gt;- .NET Runtimes (For Windows XP users). You probably have these installed already.&lt;br /&gt;&lt;br /&gt;How to use it:&lt;br /&gt;1) Install DOSRunner using the setup file.&lt;br /&gt;2) Setup will prompt you for the path of your DOSBox folder. Use the &quot;Browse&quot; button to find the dosbox.exe executable.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibO_xe4ZGjXLelfGKxu4qUgXpsgWxQ-IGjxtTTjaPuuEj9ANroywGBUpV24swGjRfVSq2ndMbAKZsea-WuM6NV_UMqPJM5AtLFBA99oQDkU7vmfH4e6Hfql3UE1l-EQBRpoZCS8Xn87Vvy/s1600/2.jpg&quot;&gt;&lt;img style=&quot;display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 320px; height: 118px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibO_xe4ZGjXLelfGKxu4qUgXpsgWxQ-IGjxtTTjaPuuEj9ANroywGBUpV24swGjRfVSq2ndMbAKZsea-WuM6NV_UMqPJM5AtLFBA99oQDkU7vmfH4e6Hfql3UE1l-EQBRpoZCS8Xn87Vvy/s320/2.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5455282638708882978&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;3) After installation, right click any executable you want to run in DOSBox, and select the &quot;Run in DOSBox&quot; option.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNNpsGCafxKbY5zKHGSNB_yax_E4foMs_uC5KcKPpDToE93EJRufcbDdPoNLEun4BsKwxTrwnFK0VzvkRCbX5Yehmv89e_rET7RRO5DSrlA7LjM3YC6y1Y-nc79PAREOhgBdLdDonCOZvW/s1600/1.jpg&quot;&gt;&lt;img style=&quot;display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 290px; height: 173px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNNpsGCafxKbY5zKHGSNB_yax_E4foMs_uC5KcKPpDToE93EJRufcbDdPoNLEun4BsKwxTrwnFK0VzvkRCbX5Yehmv89e_rET7RRO5DSrlA7LjM3YC6y1Y-nc79PAREOhgBdLdDonCOZvW/s320/1.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5455282453300798450&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;4) Play away.&lt;br /&gt;&lt;br /&gt;- Uninstallation is as easy as clicking the Uninstall link under the &quot;DOSRunner&quot; Start Menu entry.&lt;br /&gt;&lt;br /&gt;- If you want to use it with another DosBOX version, just use the DOSRunner Configurator tool in the Start Menu (Under DOSRunner).&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;NOTE:&lt;/span&gt; For this to work, you must not have modified DosBox to mount any path by default! just remove any mount commands you might have added to dosbox.conf.&lt;br /&gt;&lt;br /&gt;If you didn&#39;t understand that, it probably won&#39;t be a problem.&lt;br /&gt;&lt;br /&gt;Thanks!</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/3111975126611193791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/04/dosrunner.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3111975126611193791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3111975126611193791'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/04/dosrunner.html' title='DOSRunner'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibO_xe4ZGjXLelfGKxu4qUgXpsgWxQ-IGjxtTTjaPuuEj9ANroywGBUpV24swGjRfVSq2ndMbAKZsea-WuM6NV_UMqPJM5AtLFBA99oQDkU7vmfH4e6Hfql3UE1l-EQBRpoZCS8Xn87Vvy/s72-c/2.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-2590806320086281471</id><published>2010-03-09T04:11:00.003+08:00</published><updated>2010-03-23T19:57:20.998+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="3d"/><category scheme="http://www.blogger.com/atom/ns#" term="blender"/><title type='text'>[Blender] RC211v model - Finishing up</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTJn3u2QhjOaKW4REnugt9VyP0yDv-SK84LzOrUayj0ay1V5dFVz6SXjm0zCm4ytNPiPqtzbWUqJ0gMipudZNmhttVCD5PUOAaIEsRiIWNDgYnXC-7Gwn5j7S5MYjNs9L-K1Vtys3QcVSY/s1600-h/1.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 145px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTJn3u2QhjOaKW4REnugt9VyP0yDv-SK84LzOrUayj0ay1V5dFVz6SXjm0zCm4ytNPiPqtzbWUqJ0gMipudZNmhttVCD5PUOAaIEsRiIWNDgYnXC-7Gwn5j7S5MYjNs9L-K1Vtys3QcVSY/s320/1.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5446358643621882674&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Just the body kit and we are good to go for the final render. I have spent 9 hours total on this thing.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbip1Tc-b2zl2ZPuqX3z8Oizky-Uor72DSIIKsDhlg-dvVvKhderPME7FTIxKynktXZK5reJGU0G3jcv9CmlYM9n4j_O7JIaQVlv90KaJS2noqsw9o8cNYR4e_-FiTvZVCuuRpcX5L-vEG/s1600-h/2.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 256px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbip1Tc-b2zl2ZPuqX3z8Oizky-Uor72DSIIKsDhlg-dvVvKhderPME7FTIxKynktXZK5reJGU0G3jcv9CmlYM9n4j_O7JIaQVlv90KaJS2noqsw9o8cNYR4e_-FiTvZVCuuRpcX5L-vEG/s320/2.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5446358653211255330&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://maranas.deviantart.com/&quot;&gt;http://maranas.deviantart.com&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/2590806320086281471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/03/blender-rc211v-model-finishing-up.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/2590806320086281471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/2590806320086281471'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/03/blender-rc211v-model-finishing-up.html' title='[Blender] RC211v model - Finishing up'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgTJn3u2QhjOaKW4REnugt9VyP0yDv-SK84LzOrUayj0ay1V5dFVz6SXjm0zCm4ytNPiPqtzbWUqJ0gMipudZNmhttVCD5PUOAaIEsRiIWNDgYnXC-7Gwn5j7S5MYjNs9L-K1Vtys3QcVSY/s72-c/1.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-5984627132025377225</id><published>2010-03-03T01:14:00.004+08:00</published><updated>2010-03-03T01:22:48.899+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="games"/><title type='text'>[Game] 20XX</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmLog3oNKZzn7eN8AY9smqptcHjgsuMVhjp2SQqky6VnRVhGgBf9XHrlahF8StSwTEqsRFrX6OBShFg0xhRXHVL80hO3r_Wf3qZdShF0-HZXEhYXR0gBhiJYWMIcKLvzj_r096uERA60Af/s1600-h/20xx.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmLog3oNKZzn7eN8AY9smqptcHjgsuMVhjp2SQqky6VnRVhGgBf9XHrlahF8StSwTEqsRFrX6OBShFg0xhRXHVL80hO3r_Wf3qZdShF0-HZXEhYXR0gBhiJYWMIcKLvzj_r096uERA60Af/s320/20xx.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5444088022647393058&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Back when I was in college, everytime I went home to Quezon City from Manila, I would drop by SM North EDSA&#39;s Quantum. They had this little arcade game called &quot;19xx&quot;. And it was fucking awesome. I would buy 5 tokens at 7 pesos each and have a great time.&lt;br /&gt;&lt;br /&gt;This game I created as an homage to the legend. It isn&#39;t 19XX, but it&#39;s fast, it has lots of different enemies, and has the Big Boss fights everyone loves.&lt;br /&gt;&lt;br /&gt;20XX - &lt;a href=&quot;http://www.mediafire.com/?ycrn1m3yjhz&quot;&gt;Download Here&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Controls: Just press F1 for in-game help.</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/5984627132025377225/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/03/game-20xx.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/5984627132025377225'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/5984627132025377225'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/03/game-20xx.html' title='[Game] 20XX'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmLog3oNKZzn7eN8AY9smqptcHjgsuMVhjp2SQqky6VnRVhGgBf9XHrlahF8StSwTEqsRFrX6OBShFg0xhRXHVL80hO3r_Wf3qZdShF0-HZXEhYXR0gBhiJYWMIcKLvzj_r096uERA60Af/s72-c/20xx.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-26745682191842316</id><published>2010-02-19T07:43:00.004+08:00</published><updated>2010-02-19T07:54:40.153+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="games"/><title type='text'>[Game] Missile Command</title><content type='html'>Another day, another one of my old creations.&lt;br /&gt;&lt;br /&gt;Yesterday we had Tank Commander. Today, I give you, wait for it:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Missile Commander.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSjjushJIGWqS_rsfZHfVPus0JXBuA8TBQqw6E4ew36Eut_5daoK2THVFxSdHPZkwBtZ3ZumXJ887Rch-3bZn7KheW3-jj12afxLIDYsXp96-9dTgD-z78aUAjm0-Nh3psOMVAGlyszQA-/s1600-h/mc.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 239px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSjjushJIGWqS_rsfZHfVPus0JXBuA8TBQqw6E4ew36Eut_5daoK2THVFxSdHPZkwBtZ3ZumXJ887Rch-3bZn7KheW3-jj12afxLIDYsXp96-9dTgD-z78aUAjm0-Nh3psOMVAGlyszQA-/s320/mc.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5439735304731508210&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The game is basically a clone of &quot;Text Missile Command&quot;, but with graphics. And explosions. Originally just a test of my particle generation system in Game Maker, but turned out to be really fun, so I made a game out of it.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Controls:&lt;/span&gt;&lt;br /&gt;Just use the mouse and click on any direction you want to shoot missles at.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Download&lt;/span&gt; it from &lt;a href=&quot;http://www.mediafire.com/?w1tuyzmt01j&quot;&gt;here&lt;/a&gt;:&lt;br /&gt;&lt;a href=&quot;http://www.mediafire.com/?w1tuyzmt01j&quot;&gt;http://www.mediafire.com/?w1tuyzmt01j&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/26745682191842316/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/02/game-missile-command.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/26745682191842316'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/26745682191842316'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/02/game-missile-command.html' title='[Game] Missile Command'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSjjushJIGWqS_rsfZHfVPus0JXBuA8TBQqw6E4ew36Eut_5daoK2THVFxSdHPZkwBtZ3ZumXJ887Rch-3bZn7KheW3-jj12afxLIDYsXp96-9dTgD-z78aUAjm0-Nh3psOMVAGlyszQA-/s72-c/mc.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-676235202773043768</id><published>2010-02-18T02:54:00.005+08:00</published><updated>2010-02-18T03:00:37.799+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="games"/><title type='text'>[Game] Tank Commander</title><content type='html'>Was rummaging through my files in the old laptop when I found a whole folder full of games I made from back when I was in college. Those were the days. I&#39;ll try to upload them all, but for now here&#39;s &lt;span style=&quot;font-weight: bold;&quot;&gt;Tank Commander&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1mGwLwFIhOP34F5xKQP9Tf0DOO3vmsRDLMr78ncxJwkA8QUGy7zVyASw_LM1am5rDut7iJXCXtiin6HulRRMCiPhBMLVwRzd4cguxdHaYi0lQJEjGP5eDHCm64mLRiYeknMI6yAt5cpdB/s1600-h/tankcom.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 288px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1mGwLwFIhOP34F5xKQP9Tf0DOO3vmsRDLMr78ncxJwkA8QUGy7zVyASw_LM1am5rDut7iJXCXtiin6HulRRMCiPhBMLVwRzd4cguxdHaYi0lQJEjGP5eDHCm64mLRiYeknMI6yAt5cpdB/s320/tankcom.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5439288714442151570&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Download it from &lt;a href=&quot;http://www.mediafire.com/?ytj2zgdznm2&quot;&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Didn&#39;t get that? Here&#39;s the link: &lt;a href=&quot;http://www.mediafire.com/?ytj2zgdznm2&quot;&gt;http://www.mediafire.com/?ytj2zgdznm2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It&#39;s a top down shooter where you get to control a tank deep within enemy lines.&lt;br /&gt;&lt;br /&gt;Controls:&lt;br /&gt;W,A,S,D - drive the tank&lt;br /&gt;Mouse - control the turret&lt;br /&gt;Mouse click (left or right) - shoot with your machine gun (save your rockets, use this on infantry)&lt;br /&gt;Mouse click + space - shoot a rocket (useful for enemy tanks and barriers)&lt;br /&gt;&lt;br /&gt;Press F1 for the in-game help. Enjoy!</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/676235202773043768/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/02/game-tank-commander.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/676235202773043768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/676235202773043768'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/02/game-tank-commander.html' title='[Game] Tank Commander'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1mGwLwFIhOP34F5xKQP9Tf0DOO3vmsRDLMr78ncxJwkA8QUGy7zVyASw_LM1am5rDut7iJXCXtiin6HulRRMCiPhBMLVwRzd4cguxdHaYi0lQJEjGP5eDHCm64mLRiYeknMI6yAt5cpdB/s72-c/tankcom.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-7794796351278517757</id><published>2010-01-21T22:50:00.012+08:00</published><updated>2010-11-25T02:16:00.091+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="haiku"/><category scheme="http://www.blogger.com/atom/ns#" term="virtualization"/><title type='text'>[Virtualization] Haiku on VirtualBox</title><content type='html'>Remember &lt;a href=&quot;http://en.wikipedia.org/wiki/BeOS&quot;&gt;BeOS&lt;/a&gt;? Those of you missing the BeOS&#39;s beautiful simplicity would be glad to know that &lt;a href=&quot;http://www.haiku-os.org/&quot;&gt;Haiku&lt;/a&gt;, an open source OS project inspired by BeOS, is already in alpha1. The great thing about it is, it is mostly compatible with your old BeOS software.&lt;br /&gt;&lt;br /&gt;So let&#39;s get it running in &lt;a href=&quot;http://www.virtualbox.org/&quot;&gt;VirtualBox&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;1) If you haven&#39;t already, download and install &lt;a href=&quot;http://www.virtualbox.org/wiki/Downloads&quot;&gt;VirtualBox&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;2) Get the latest haiku ISO file from the &lt;a href=&quot;http://www.haiku-os.org/get-haiku&quot;&gt;haiku project website&lt;/a&gt;. Unzip it to any convenient location.&lt;br /&gt;&lt;br /&gt;3) In VirtualBox, Create a New Virtual Machine with the following settings:&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHSTELKJVKvke-cxuDVtSeGa7JT2jT24yvIAimg4aXXj8B5PsD_v38u1yXl3CCtD1m7ohZ6ex748jhbKUgHPkCS3HcyxI-WC9xKhi8hDMsmqg-O9aNQNVpjrJ6wnk5DsmnKqvMOW-6f86i/s1600-h/screen1.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 234px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHSTELKJVKvke-cxuDVtSeGa7JT2jT24yvIAimg4aXXj8B5PsD_v38u1yXl3CCtD1m7ohZ6ex748jhbKUgHPkCS3HcyxI-WC9xKhi8hDMsmqg-O9aNQNVpjrJ6wnk5DsmnKqvMOW-6f86i/s320/screen1.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429208728095765730&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;Name: haiku&lt;br /&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;div style=&quot;text-align: center;&quot;&gt;Operating System: Other&lt;br /&gt;&lt;/div&gt;&lt;div style=&quot;text-align: left;&quot;&gt;&lt;div style=&quot;text-align: center;&quot;&gt;Version: Other/Unknown&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzXHhzKZHbu-kLzxCDtr_XSBbw1lCbbNJIdpRuRYJmDD6Xf8SiW50t4oPLcqTfQzkDHAF1_95cSosrqdFwIvCNPVE258OstwIbPHyBOPRL8MR0UCHZr0bLFVN4XXpUyXNArWhZvdXh2HxY/s1600-h/screen2.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 234px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzXHhzKZHbu-kLzxCDtr_XSBbw1lCbbNJIdpRuRYJmDD6Xf8SiW50t4oPLcqTfQzkDHAF1_95cSosrqdFwIvCNPVE258OstwIbPHyBOPRL8MR0UCHZr0bLFVN4XXpUyXNArWhZvdXh2HxY/s320/screen2.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429208717172828850&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div style=&quot;text-align: center;&quot;&gt;Base Memory Size: 512MB. (you may be able to get away with less, but this one worked for me)&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxD7-RknLiwPMe3LHa48Xrw2sc2KahxsCZYxUOCYJjhbxTdIlPXzIvaKSgNuD8tyUrhxdbQ9UK2Icty2YasEFt1S3VtCxIi25VDrFZXg-lz_t-z45iOLwd4BoxAoSdCNcfL_5KXLdowr0t/s1600-h/screen3.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 234px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxD7-RknLiwPMe3LHa48Xrw2sc2KahxsCZYxUOCYJjhbxTdIlPXzIvaKSgNuD8tyUrhxdbQ9UK2Icty2YasEFt1S3VtCxIi25VDrFZXg-lz_t-z45iOLwd4BoxAoSdCNcfL_5KXLdowr0t/s320/screen3.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429208713594479074&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Select &quot;Create a new hard disk&quot;. It is up to you how you want to set up your hard disk, but preferably, just select the Fixed Size hard disk and give it the amount of disk space you prefer. I gave mine 5GB.&lt;br /&gt;&lt;br /&gt;4) Once that&#39;s done, you should be able to see the new virtual machine in the list. Select your virtual machine, then press the &quot;Settings&quot; button.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLYNKiYJaIdmr40YEAIAGQLSoqG_FQDGo6lyOfSdGDy5q9LpEtde6YYGTNS-swJ6UTxrpq3oE_hfG3QXr5C5giW7rKDzvlVIDpKzXqmj9tB03Q3BVCi0CMJX8asHUf7tiuiNclh9CDivHo/s1600-h/sett.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 238px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLYNKiYJaIdmr40YEAIAGQLSoqG_FQDGo6lyOfSdGDy5q9LpEtde6YYGTNS-swJ6UTxrpq3oE_hfG3QXr5C5giW7rKDzvlVIDpKzXqmj9tB03Q3BVCi0CMJX8asHUf7tiuiNclh9CDivHo/s320/sett.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429210380454020194&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;5) Go to the &quot;Display&quot; item. Give the virtual machine some video memory. I gave mine 128MB. You may get away with less, but again, this worked for me.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2cLi1K6NfI4096ZdHrcWP_XFZ96ht4MQx9FsUTmJ2kFjxK6uWThw_4cc0gr5P9iRWJVNkPmNIyNul2dEaU52C8otrHX3iK-uKAqrBf7_5bYEaXiOdyW72kYfp6UV8bDs0U-CPgZ-1OYps/s1600-h/video.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 231px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2cLi1K6NfI4096ZdHrcWP_XFZ96ht4MQx9FsUTmJ2kFjxK6uWThw_4cc0gr5P9iRWJVNkPmNIyNul2dEaU52C8otrHX3iK-uKAqrBf7_5bYEaXiOdyW72kYfp6UV8bDs0U-CPgZ-1OYps/s320/video.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429211635208167906&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;6) Go to the &quot;Storage&quot; item. Click on the CD-like icon in the tree, then click on the button beside the drop-down box with &quot;Empty&quot; as a value. (See the button marked with the red box in the screenshot). This will bring up the Virtual Media Manager. Just click on the Add button, browse to the Haiku iso you downloaded and extracted earlier, then select it from the list.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhntPOBBYF5AmhHaHHSGA_DNJ3iFZOsAkZmBeR-goUaEIM3bKLhKrNer83cbVgvgQUJEOA0Rj4osIPvp5WKJe_IDEm_Dr5v3a7OAbI6fv12WbaZwZmvmTwoGHrYMXaFNla6iaV9R9R05Tqg/s1600-h/step1.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 231px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhntPOBBYF5AmhHaHHSGA_DNJ3iFZOsAkZmBeR-goUaEIM3bKLhKrNer83cbVgvgQUJEOA0Rj4osIPvp5WKJe_IDEm_Dr5v3a7OAbI6fv12WbaZwZmvmTwoGHrYMXaFNla6iaV9R9R05Tqg/s320/step1.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429211627041395762&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;7) Go to the &quot;Network&quot; item. Click on &quot;Advanced&quot;. Select any Adapter Type EXCEPT for the PCInet ones. They don&#39;t seem to work with haiku. The &lt;span style=&quot;font-weight: bold;&quot;&gt;Intel PRO 1000/MT Desktop (82540EM)&lt;/span&gt; worked for me.&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF020QLnvdtqf04JHwVBDFBFpQW6euXL5adk3DX6g3UXEJ1uRGBR3zl118Cw7PJR4EWv8HnjYJnJctGYttWlS1cDKMK4UcpmmNTVwWMBHMcKimh5Jd6v2Sg3eDjOX261DtbrtKzy5vrT_W/s1600-h/net.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 231px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF020QLnvdtqf04JHwVBDFBFpQW6euXL5adk3DX6g3UXEJ1uRGBR3zl118Cw7PJR4EWv8HnjYJnJctGYttWlS1cDKMK4UcpmmNTVwWMBHMcKimh5Jd6v2Sg3eDjOX261DtbrtKzy5vrT_W/s320/net.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429212947898903250&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;8) Click &quot;OK&quot;. You are now ready to boot the ISO you downloaded. Select haiku from the Virtual Machine list and click on &quot;Start&quot;.&lt;br /&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiVqj8UHz20Kny6TCFOTcl_Xn5hy4E4UCSb3vDNwEpKvuTV3xW2XVyNURsTWl6oZM2XsZyUdS-jCu3VXaolUD2WyXzEFEcmu1z6ACX11LUV3pR_ssq4jof0t_0Y4bHCr7c6UjCcla74wYb/s1600-h/boot+screen.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 239px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiVqj8UHz20Kny6TCFOTcl_Xn5hy4E4UCSb3vDNwEpKvuTV3xW2XVyNURsTWl6oZM2XsZyUdS-jCu3VXaolUD2WyXzEFEcmu1z6ACX11LUV3pR_ssq4jof0t_0Y4bHCr7c6UjCcla74wYb/s320/boot+screen.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429219284225828562&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Haiku boot screen&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;9) Once it boots, click on the &quot;Installer&quot; button. Read and agree with the license.&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzL4K_j8EIXC2LPzt_F0ycoEZQr88EMwNlCrV4RUzSUTZhEQvAzG-xz5mIOBkxGSm10W0kgUnj69T8u-W4CUnD4VZa0hnbkgbqxCkai_KWz8_86JTS7DTrJxN69daaTPwxmVmaYNJBQurf/s1600-h/installer.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 87px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzL4K_j8EIXC2LPzt_F0ycoEZQr88EMwNlCrV4RUzSUTZhEQvAzG-xz5mIOBkxGSm10W0kgUnj69T8u-W4CUnD4VZa0hnbkgbqxCkai_KWz8_86JTS7DTrJxN69daaTPwxmVmaYNJBQurf/s320/installer.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429215847495535714&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;10) In the next dialog, click on &quot;Setup partitions...&quot;:&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrlUvRbskZwRAbmTka70pgfl3M-PrssmbeAfkLJEmJUT8zfv764YWtXYtJUJzf23vgg99rjY8l-vVBuUu1ZxywjXB7GERG3aMkW41JqXJDbpw3EWo6pzozkizCzPvh1v3ww_8A49qyDKal/s1600-h/part.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 200px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrlUvRbskZwRAbmTka70pgfl3M-PrssmbeAfkLJEmJUT8zfv764YWtXYtJUJzf23vgg99rjY8l-vVBuUu1ZxywjXB7GERG3aMkW41JqXJDbpw3EWo6pzozkizCzPvh1v3ww_8A49qyDKal/s320/part.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429215843020485698&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;11) Select the disk you created earlier. Then click on Partition-&gt;Initialize-&gt;Be File System. After initialization is done, you can close this window (By pressing the small square on the top-left corner of the window).&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEia0L5A0DGIKoetrjRw0LUWB4DFN-O-qbBr3LEbhJAgCjDwoOmOzBjsHwgP4v8eg3TquGKHWu6WXxxGpzUgETZ4zs7EHo1_FwU2ZOC-akTJUR4KBIszWo8ZckIG6dp79f5KeA5GKefisLQ9/s1600-h/be+file+system.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 203px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEia0L5A0DGIKoetrjRw0LUWB4DFN-O-qbBr3LEbhJAgCjDwoOmOzBjsHwgP4v8eg3TquGKHWu6WXxxGpzUgETZ4zs7EHo1_FwU2ZOC-akTJUR4KBIszWo8ZckIG6dp79f5KeA5GKefisLQ9/s320/be+file+system.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429215838705817394&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;12) Select the drive you initialized in the &quot;Onto:&quot; drop down, and press Begin. This will install haiku onto the hard drive you created earlier.&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJsKxOJnIzyFBHZiXweOGYBPjEd9f0H38G1fFCKG7kDi88Hy7jMbbug9uo2iybX-up93lDyPapQD8NJkxI5R9D2G2Q1U9mRLkaFsFKf5edbl1_fBZY2mCCEEOSR7uIWRw6scAMjHOjyaNo/s1600-h/begin.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 202px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJsKxOJnIzyFBHZiXweOGYBPjEd9f0H38G1fFCKG7kDi88Hy7jMbbug9uo2iybX-up93lDyPapQD8NJkxI5R9D2G2Q1U9mRLkaFsFKf5edbl1_fBZY2mCCEEOSR7uIWRw6scAMjHOjyaNo/s320/begin.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429215834567269026&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;13) After installation, close the virtual machine. Go back to the &quot;Settings&quot; of the virtual machine. under &quot;Storage&quot;, deselect the haiku ISO you loaded earlier by clicking on the drop-down and selecting &quot;Empty&quot; (see screenshot). This will prevent the virtual machine from booting into the install ISO when you restart it. Click &quot;OK&quot;.&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjruvh38kTNhxSeF_GDKYs3Rn4rzJcT9qOHKfpk_fz-QdsbZYPBztiw9SRncgfoVMTDr9dzSop_jf27o4kBaAYHK3gHc9elfqdVY0pVKsbOdQBcOjnEoADDIFXDsY6mAHF5UakZCw_k8PdE/s1600-h/unload+CD.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 231px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjruvh38kTNhxSeF_GDKYs3Rn4rzJcT9qOHKfpk_fz-QdsbZYPBztiw9SRncgfoVMTDr9dzSop_jf27o4kBaAYHK3gHc9elfqdVY0pVKsbOdQBcOjnEoADDIFXDsY6mAHF5UakZCw_k8PdE/s320/unload+CD.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429215821454651538&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;14) You&#39;re almost there. select haiku again from your list of virtual machines, and press &quot;Start&quot;. After a few seconds, you will be greeted with the Haiku desktop.&lt;br /&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcN5-Q4tZHXX0geIxvEqn69pI-jmbj5XqzR60kvFUppODjA5gum6uSRFYLootjT56DQ3c_44cYLV-K1ZS9KytT79AD15z-HyNJkZRpJy5oF7H7X9Nm8LwpHuAe78NP-lghgu9odJ3P7_m2/s1600-h/desktop.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 238px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcN5-Q4tZHXX0geIxvEqn69pI-jmbj5XqzR60kvFUppODjA5gum6uSRFYLootjT56DQ3c_44cYLV-K1ZS9KytT79AD15z-HyNJkZRpJy5oF7H7X9Nm8LwpHuAe78NP-lghgu9odJ3P7_m2/s320/desktop.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429219297923377938&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;Haiku Desktop&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM90vIcBt6RJTrfISmfeE4nzt8kVv-CzO1hqD-6a0YdOTE0kdlcI6toqEMr8Id966NcrLKET-KOY7XVGiDb3oeJArDynJWNM55b03-Fpt_2yhrb13MBpOadhu1kAj2yCRZPik5MRXya7dz/s1600-h/glteapot.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 240px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhM90vIcBt6RJTrfISmfeE4nzt8kVv-CzO1hqD-6a0YdOTE0kdlcI6toqEMr8Id966NcrLKET-KOY7XVGiDb3oeJArDynJWNM55b03-Fpt_2yhrb13MBpOadhu1kAj2yCRZPik5MRXya7dz/s320/glteapot.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5429219294311002178&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;GLTeapot demo (running at 227.5FPS) and Bon Echo (Firefox port) browsing Google&lt;/span&gt;&lt;br /&gt;&lt;/div&gt;&lt;br /&gt;There you go. Your very own haiku &lt;a href=&quot;http://www.virtualbox.org/&quot;&gt;VirtualBox&lt;/a&gt;. Don&#39;t forget to check out the following sites for software:&lt;br /&gt;&lt;a href=&quot;http://www.haiku-os.org/&quot;&gt;http://www.haiku-os.org/&lt;/a&gt; - Haiku project page&lt;br /&gt;&lt;a href=&quot;http://www.haikuware.com/&quot;&gt;http://www.haikuware.com/&lt;/a&gt; - Haikuware - Software for Haiku OS&lt;br /&gt;&lt;a href=&quot;http://www.bebits.com/&quot;&gt;http://ports.haiku-files.org/&lt;/a&gt; - Haiku Ports&lt;br /&gt;&lt;a href=&quot;http://zeta-games.com/&quot;&gt;http://zeta-games.com/&lt;/a&gt; - Zeta Games - games for BeOS/Haiku&lt;br /&gt;&lt;a href=&quot;http://zeta-games.com/&quot;&gt;http://www.bebits.com/&lt;/a&gt; - BeBits - BeOS software</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/7794796351278517757/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/01/virtualization-haiku-on-virtualbox.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/7794796351278517757'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/7794796351278517757'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/01/virtualization-haiku-on-virtualbox.html' title='[Virtualization] Haiku on VirtualBox'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHSTELKJVKvke-cxuDVtSeGa7JT2jT24yvIAimg4aXXj8B5PsD_v38u1yXl3CCtD1m7ohZ6ex748jhbKUgHPkCS3HcyxI-WC9xKhi8hDMsmqg-O9aNQNVpjrJ6wnk5DsmnKqvMOW-6f86i/s72-c/screen1.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-7542737992109202964</id><published>2010-01-07T23:28:00.013+08:00</published><updated>2010-01-08T00:06:19.399+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="keylogger"/><category scheme="http://www.blogger.com/atom/ns#" term="tools"/><title type='text'>[Tools] Keylogger utility</title><content type='html'>I was playing around with CodeProject when I came across this &lt;a href=&quot;http://www.codeproject.com/KB/system/globalsystemhook.aspx&quot;&gt;article by Michael Kennedy&lt;/a&gt; on how to create global system hooks in managed code. I know local hooks are possible with C#, but for global hooks you would need to build a DLL in C++ (there are no methods for hooking to system events in C#.NET), then use P/Invoke to access the DLL in C#.&lt;br /&gt;&lt;br /&gt;Using his managed system hook library, I created a keylogger that logs keyboard input into a textfile:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.mediafire.com/?qodm3zzj4nm&quot;&gt;Download here&lt;/a&gt;&lt;a href=&quot;http://www.mediafire.com/?qodm3zzj4nm&quot;&gt;&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Note&lt;/span&gt;: It may or may not work with 64-bit PCs. I only tested it with 32-bit XP and Vista.&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Usage:&lt;/span&gt;&lt;br /&gt;Just run the program. It is hidden (there is no visible form); you will only see it in the Processes tab of task manager. It will save the log into the directory it is stored in.&lt;br /&gt;&lt;br /&gt;To quit the program, just press &lt;span style=&quot;font-weight: bold;&quot;&gt;Shift+F11.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Output Files:&lt;/span&gt;&lt;br /&gt;The filename is of the following format:&lt;span style=&quot;font-family:courier new;&quot;&gt; &lt;span style=&quot;font-weight: bold;&quot;&gt;Month-Day-Year.txt&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;The keylogger outputs the key events as readable text. The words will be readable as much as possible, and the output is case sensitive. But, since other types of keys are also handled (e.g. Fn keys, Ctrl, Alt, Home, End, etc.), there will be non-readable portions.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Sample output:&lt;/span&gt;&lt;br /&gt;Filename: &lt;span style=&quot;font-family: courier new;&quot;&gt;1-8-2010.txt&lt;/span&gt;&lt;br /&gt;Contents:&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEYControl was pressed.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;a&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEY Control was released.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;the quick brown fox&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;is&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEYBack was pressed.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEY Back was released.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEYBack was pressed.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEY Back was released.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEYBack was pressed.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEY Back was released.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;was not megan&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;12345&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;asfaf&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEYHome was pressed.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEY Home was released.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEYEnd was pressed.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEY End was released.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEYDelete was pressed.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEY Delete was released.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEYDelete was pressed.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEY Delete was released.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEYDelete was pressed.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEY Delete was released.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEYDelete was pressed.&lt;/span&gt;&lt;br /&gt;&lt;span style=&quot;font-family: courier new;&quot;&gt;KEY Delete was released.&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;I am not responsible for anything you do with it. It is provided as-is, without any warranty of any kind.&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/7542737992109202964/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/01/tools-keylogger-for-x86-cpus.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/7542737992109202964'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/7542737992109202964'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/01/tools-keylogger-for-x86-cpus.html' title='[Tools] Keylogger utility'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-3601451852732241991</id><published>2010-01-02T03:10:00.005+08:00</published><updated>2010-01-02T03:24:41.491+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="3d"/><category scheme="http://www.blogger.com/atom/ns#" term="blender"/><title type='text'>[Blender] RC211v model - Day Eight</title><content type='html'>Today I was playing around with the materials I will use for the bike. I figured, since the only thing left to be modeled is the body kit, I would prepare the materials for everything underneath before I cover it up.&lt;br /&gt;&lt;br /&gt;&lt;div style=&quot;text-align: center;&quot;&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgArYUcKj7_H_D0iOA_XfVXxElZonj67Z9Bm2EnLnzJqq6qoreLC4P2jOJQN2lmvnYgh38CHz8EEjTg_hhCUpOi0SeumqfqyHLiketO2F0ZyOLdY65JuqCZBx8T0zeBVHwK4cExOXO5LW_z/s1600-h/test+render.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 227px; height: 181px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgArYUcKj7_H_D0iOA_XfVXxElZonj67Z9Bm2EnLnzJqq6qoreLC4P2jOJQN2lmvnYgh38CHz8EEjTg_hhCUpOi0SeumqfqyHLiketO2F0ZyOLdY65JuqCZBx8T0zeBVHwK4cExOXO5LW_z/s320/test+render.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5421850999152045810&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;(click the image for a larger view)&lt;br /&gt;&lt;br /&gt;&lt;/div&gt;The chrome material isn&#39;t looking too good; it is reflecting the ridges of the radiator. And it doesn&#39;t look like chrome at all.&lt;br /&gt;&lt;br /&gt;The rubber on the tires look OK, but will still need some tweaking. The leather seats look OK too, but you can&#39;t see it that well from the screenshot. The black plastic material is a little too black, I think. Comments are welcome here. I just couldn&#39;t stand another render with Blender&#39;s internal renderer - took me 15 minutes. After two test renders I was done.&lt;br /&gt;&lt;br /&gt;Also, I realized, the materials don&#39;t work in Yafaray. So I&#39;d have to redo everything for a Yafaray render.&lt;br /&gt;&lt;br /&gt;The gradient background isn&#39;t supposed to look like that. I just wanted a plane to show the shadows. I should have just used a cube. Come to think of it, if I had used a cube instead of a subsurfed plane, the render wouldn&#39;t have been that time-consuming. Dammit.&lt;br /&gt;&lt;br /&gt;The body paint looks good. I actually downloaded this material from &lt;a href=&quot;http://www.blender-materials.org/&quot;&gt;blender-materials.org&lt;/a&gt; (it isn&#39;t up yet, but it points you to the old site &lt;a href=&quot;http://matrep.parastudios.de/&quot;&gt;here&lt;/a&gt;, which has the actual database). Materials are my weakness in blender. I do not yet fully understand the blender materials system, but I&#39;ll get there.&lt;br /&gt;&lt;br /&gt;That&#39;s it for today. Tomorrow - model the body kit. I wish.&lt;br /&gt;&lt;br /&gt;For more works, see my deviantart gallery at:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://maranas.deviantart.com/&quot;&gt;http://maranas.deviantart.com&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/3601451852732241991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2010/01/blender-rc211v-model-day-eight.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3601451852732241991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3601451852732241991'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2010/01/blender-rc211v-model-day-eight.html' title='[Blender] RC211v model - Day Eight'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgArYUcKj7_H_D0iOA_XfVXxElZonj67Z9Bm2EnLnzJqq6qoreLC4P2jOJQN2lmvnYgh38CHz8EEjTg_hhCUpOi0SeumqfqyHLiketO2F0ZyOLdY65JuqCZBx8T0zeBVHwK4cExOXO5LW_z/s72-c/test+render.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-6357396982619607490</id><published>2009-12-31T03:18:00.004+08:00</published><updated>2009-12-31T03:25:52.059+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="3d"/><category scheme="http://www.blogger.com/atom/ns#" term="blender"/><title type='text'>[Blender] RC211v model - Day Seven</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqcGPHQPOZE07jFvVdRHj5eElwiVqHsaBt8z_ykEBj0GBFhFOh0rW_oWkduvMZDB5WIaWOkj5sml_oo3PyCWqMTqRjdUiqvOmzrXpKyD-7I58E-g7eXGsOeDPCgC-onSK2uGSYPxTnqrB9/s1600-h/screen7.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 194px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqcGPHQPOZE07jFvVdRHj5eElwiVqHsaBt8z_ykEBj0GBFhFOh0rW_oWkduvMZDB5WIaWOkj5sml_oo3PyCWqMTqRjdUiqvOmzrXpKyD-7I58E-g7eXGsOeDPCgC-onSK2uGSYPxTnqrB9/s320/screen7.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5421111056604102514&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;It is day 7 of my holiday blender modeling marathon. And with another day comes another unproductive hour of modeling.&lt;br /&gt;&lt;br /&gt;Handlebars are done, the brakelines too.&lt;br /&gt;&lt;br /&gt;Only the bodykit remains to be modeled (along with the windscreen).&lt;br /&gt;&lt;br /&gt;The screenshot isn&#39;t that smooth; all subsurf modifiers are set to level 1 for modeling purposes. I will set them to level 3-4 when I&#39;ll do the final render.&lt;br /&gt;&lt;br /&gt;I cannot wait to put materials on it, but I tend to go lazy when I rush things. So I will continue tomorrow.&lt;br /&gt;&lt;br /&gt;Plus, I have my FIFA10 season to play with. As the manager of Crystal Palace.&lt;br /&gt;&lt;br /&gt;Yafaray render:&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikA7ymxHGZQfxZKdr3vh6l3Kp3DWi9CsmhidMKCt0nkzzCnoNMYICA7f_ZwMpcmqjxs9ZkQk6n6qACjNj8lKtNhFhfaVyNidQNASaRRUsvL4TVlKYR-07Cy-vmm7RCUWY80r_wHVxt-RbI/s1600-h/screen7.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 256px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikA7ymxHGZQfxZKdr3vh6l3Kp3DWi9CsmhidMKCt0nkzzCnoNMYICA7f_ZwMpcmqjxs9ZkQk6n6qACjNj8lKtNhFhfaVyNidQNASaRRUsvL4TVlKYR-07Cy-vmm7RCUWY80r_wHVxt-RbI/s320/screen7.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5421111046810626690&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;For more works, please check out my deviantart gallery:&lt;br /&gt;&lt;a href=&quot;http://maranas.deviantart.com/&quot;&gt;http://maranas.deviantart.com&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/6357396982619607490/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-seven.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/6357396982619607490'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/6357396982619607490'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-seven.html' title='[Blender] RC211v model - Day Seven'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgqcGPHQPOZE07jFvVdRHj5eElwiVqHsaBt8z_ykEBj0GBFhFOh0rW_oWkduvMZDB5WIaWOkj5sml_oo3PyCWqMTqRjdUiqvOmzrXpKyD-7I58E-g7eXGsOeDPCgC-onSK2uGSYPxTnqrB9/s72-c/screen7.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-3371890146910822245</id><published>2009-12-30T04:58:00.003+08:00</published><updated>2009-12-30T05:04:54.450+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="3d"/><category scheme="http://www.blogger.com/atom/ns#" term="blender"/><title type='text'>[Blender] RC211v model - Day Six</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8ZPOgnCEnNCMvXcaUXIHHzt9zJBeVAB_T6jyARSdcEci2A4A9e9V7sNyD68lG24QQjspmhT32labilHmDx3_nMy08VC1aGf3QmFFJRC_E1DC_PtdKI0gj0_0nlgrFIBna0DWAc06ndnoT/s1600-h/screen6.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 194px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8ZPOgnCEnNCMvXcaUXIHHzt9zJBeVAB_T6jyARSdcEci2A4A9e9V7sNyD68lG24QQjspmhT32labilHmDx3_nMy08VC1aGf3QmFFJRC_E1DC_PtdKI0gj0_0nlgrFIBna0DWAc06ndnoT/s320/screen6.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5420765808471497570&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Another unproductive day modeling-wise; I only spent 1 hour on the model today. Damn you, FIFA10! Oh well - it IS the christmas/new year break.&lt;br /&gt;&lt;br /&gt;I was barely able to finish the front and rear brakes. The model is almost complete, though. Only the handlebars, wiring and bodykit (windscreen and engine cover) to go.&lt;br /&gt;&lt;br /&gt;Yafaray render:&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqVbJD48NSjAywXe5zc6Cz3UXlYKpwnjny9ucy5xl-NH7gDrNeUrpajsVft8xf_-2D0nBMoYaHNKX-Ee2Nl5nicPH1n9pCZUmzcW6v9Jt79HQ3j8tifAQQ71aOCWjDxuR9VHKokBJW_PRg/s1600-h/screen6.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 256px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjqVbJD48NSjAywXe5zc6Cz3UXlYKpwnjny9ucy5xl-NH7gDrNeUrpajsVft8xf_-2D0nBMoYaHNKX-Ee2Nl5nicPH1n9pCZUmzcW6v9Jt79HQ3j8tifAQQ71aOCWjDxuR9VHKokBJW_PRg/s320/screen6.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5420765803193764114&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;For more works. see my deviantart gallery at:&lt;br /&gt;&lt;a href=&quot;http://maranas.deviantart.com/&quot;&gt;http://maranas.deviantart.com&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/3371890146910822245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-six.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3371890146910822245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3371890146910822245'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-six.html' title='[Blender] RC211v model - Day Six'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8ZPOgnCEnNCMvXcaUXIHHzt9zJBeVAB_T6jyARSdcEci2A4A9e9V7sNyD68lG24QQjspmhT32labilHmDx3_nMy08VC1aGf3QmFFJRC_E1DC_PtdKI0gj0_0nlgrFIBna0DWAc06ndnoT/s72-c/screen6.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-3968530251842084432</id><published>2009-12-26T04:07:00.007+08:00</published><updated>2009-12-26T04:36:41.441+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="3d"/><category scheme="http://www.blogger.com/atom/ns#" term="blender"/><title type='text'>[Blender] RC211v model - Day Five</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgWO3SOrkO0HmZltbOPqrpqib_zrTI75qxADu5aB1w1ofc9W7hWao9J-AGWfFTQpbKdx9k46F_mDV_A7V87yEW8AV6C04l6qxLocfsh0zSWHZl8FI5NTLHzwLcXxfTIgkx08gDfMek-LRW/s1600-h/day5.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 190px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgWO3SOrkO0HmZltbOPqrpqib_zrTI75qxADu5aB1w1ofc9W7hWao9J-AGWfFTQpbKdx9k46F_mDV_A7V87yEW8AV6C04l6qxLocfsh0zSWHZl8FI5NTLHzwLcXxfTIgkx08gDfMek-LRW/s320/day5.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5419268301529315922&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Today wasn&#39;t really productive modeling-wise; I wasn&#39;t able to meet the goals set yesterday (brakes, handlebars). I spent most of this night scouring the &lt;a href=&quot;http://blenderart.org/&quot;&gt;Blenderart&lt;/a&gt; site for the magazine issues. So much information! You have to check them out.&lt;br /&gt;&lt;br /&gt;I also found the perfect tutorial on spin modeling (see &lt;a href=&quot;http://blenderart.org/issues/&quot;&gt;issue 5&lt;/a&gt;), a whole issue on modeling vehicles (&lt;a href=&quot;http://blenderart.org/issues/&quot;&gt;issue 8&lt;/a&gt;), and an issue with an article on making tracks (&lt;a href=&quot;http://blenderart.org/issues/&quot;&gt;issue 11&lt;/a&gt;), which may prove useful if I decide to stop putting off modeling the chains.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;Note:&lt;/span&gt; When downloading their issues, try using the mirrors as much as possible, to help them lower their bandwidth costs. Better yet, use the .torrent.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;As for my current progress, I finished up modeling the wheels. I did not start on the brakes yet, as I realized, I have to model the wheels first. You may notice from the screenshots that the subsurf level is set to 1; I am having issues with slow response time due to high facecounts with subsurf on a level higher than 2. The model you see above has subsurf for all parts at level 1 only, hence the blockiness.&lt;br /&gt;&lt;br /&gt;It is starting to look like a complete &quot;naked&quot; bike.&lt;br /&gt;&lt;br /&gt;Yafaray render:&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvDzGVg_0hEDWvxCHtjHWK_8IsY8Mi4KLBBZb2rzeyVzH5ixJjVtUH0axk8k3vzOf2jAUpmmaeaNmrKct51Cwnr0v2NFykENLppCHrwEF0qHeBze-D137yxIL-SVOP4Xi6FMRGQSADiNPS/s1600-h/day5.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 256px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvDzGVg_0hEDWvxCHtjHWK_8IsY8Mi4KLBBZb2rzeyVzH5ixJjVtUH0axk8k3vzOf2jAUpmmaeaNmrKct51Cwnr0v2NFykENLppCHrwEF0qHeBze-D137yxIL-SVOP4Xi6FMRGQSADiNPS/s320/day5.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5419268302948484050&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;For more works, see my deviantart gallery at:&lt;br /&gt;&lt;a href=&quot;http://maranas.deviantart.com/&quot;&gt;http://maranas.deviantart.com&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/3968530251842084432/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-five.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3968530251842084432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3968530251842084432'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-five.html' title='[Blender] RC211v model - Day Five'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgWO3SOrkO0HmZltbOPqrpqib_zrTI75qxADu5aB1w1ofc9W7hWao9J-AGWfFTQpbKdx9k46F_mDV_A7V87yEW8AV6C04l6qxLocfsh0zSWHZl8FI5NTLHzwLcXxfTIgkx08gDfMek-LRW/s72-c/day5.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-4497752907271569366</id><published>2009-12-25T03:26:00.004+08:00</published><updated>2009-12-25T03:39:15.367+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="3d"/><category scheme="http://www.blogger.com/atom/ns#" term="blender"/><title type='text'>[Blender] RC211v model - Day Four</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCpsyE_2GLRLHEfNDOVEghcfn8AFtMjnnXHacQOVK483vkhV6aEDK3GWhoPtSgx_tPTbundMljt3R-_osY06arONfKhBiHI_qh3FVcIuKO69VFLdc5lOZq66jbPbmk_USjHy3Ny_TSOoR4/s1600-h/screen4.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 190px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCpsyE_2GLRLHEfNDOVEghcfn8AFtMjnnXHacQOVK483vkhV6aEDK3GWhoPtSgx_tPTbundMljt3R-_osY06arONfKhBiHI_qh3FVcIuKO69VFLdc5lOZq66jbPbmk_USjHy3Ny_TSOoR4/s320/screen4.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5418888294720072018&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It&#39;s Christmas, just had some noche buena and I am full to the brim. Remind me to run at least five miles tomorrow.&lt;br /&gt;&lt;br /&gt;So before sleeping I thought I&#39;d put in a little work on the RC211V. I am giving myself a break from violin practice today; my ears are starting to hurt.&lt;br /&gt;&lt;br /&gt;I was able to finish the exhausts and radiator. Spent most of the time on the radiator, though; I had to manually extrude the ridges. Each one. Awesome.&lt;br /&gt;&lt;br /&gt;The facecount is pretty high now, and it is starting to slow down my PC; I had to group the parts with similar materials into their own layers and lower the subsurf levels to make it a little snappier.&lt;br /&gt;&lt;br /&gt;Tomorrow, I&#39;ll do the handlebars and the brakes. I still haven&#39;t found out how to do the chains, but if I have time left over I might start doing the wheels.&lt;br /&gt;&lt;br /&gt;One more thing, &lt;a href=&quot;http://blenderart.org&quot;&gt;blenderart.org&lt;/a&gt; produces the BlenderArt magazine, and all of their issues feature tutorials on several aspects of using blender. I highly recommend checking them out.&lt;br /&gt;&lt;br /&gt;Yafaray clay render:&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_9HMV8RkSeElQBuuP7H1r0EJgcG6HSbUGf_KofiUwHcnVLywnTjpT4uEx4oivEV9Tpk7WOQnx_WaETmWZ9IgunNyTpOdtZN9vyeo7ptqwBZM5gMVgXPmXs5rhJA_OGyoORNWkCoIS1p4Q/s1600-h/day4.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 256px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_9HMV8RkSeElQBuuP7H1r0EJgcG6HSbUGf_KofiUwHcnVLywnTjpT4uEx4oivEV9Tpk7WOQnx_WaETmWZ9IgunNyTpOdtZN9vyeo7ptqwBZM5gMVgXPmXs5rhJA_OGyoORNWkCoIS1p4Q/s320/day4.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5418888304259053618&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For more works, see my deviantart gallery at:&lt;br /&gt;&lt;a href=&quot;http://maranas.deviantart.com/&quot;&gt;http://maranas.deviantart.com&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Merry Christmas!</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/4497752907271569366/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-four.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/4497752907271569366'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/4497752907271569366'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-four.html' title='[Blender] RC211v model - Day Four'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCpsyE_2GLRLHEfNDOVEghcfn8AFtMjnnXHacQOVK483vkhV6aEDK3GWhoPtSgx_tPTbundMljt3R-_osY06arONfKhBiHI_qh3FVcIuKO69VFLdc5lOZq66jbPbmk_USjHy3Ny_TSOoR4/s72-c/screen4.jpg" height="72" width="72"/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-3186914309188318997</id><published>2009-12-24T03:16:00.007+08:00</published><updated>2009-12-24T21:57:59.319+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="3d"/><category scheme="http://www.blogger.com/atom/ns#" term="blender"/><title type='text'>[Blender] RC211v model - Day Three</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ8MDb9wInPlO95quPNKzC6Gtkhf8PWepAbk0yCWF7RGuPc_cp8u9r-pVZJh7fO14MfH_QNNRdlP9wXBNyxvc8Nrt66P0lz9DXTCKqT4qFkJphYLhwYatdX_SWm-UBGuoFSu02jXfhYRWw/s1600-h/screen3.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 190px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ8MDb9wInPlO95quPNKzC6Gtkhf8PWepAbk0yCWF7RGuPc_cp8u9r-pVZJh7fO14MfH_QNNRdlP9wXBNyxvc8Nrt66P0lz9DXTCKqT4qFkJphYLhwYatdX_SWm-UBGuoFSu02jXfhYRWw/s320/screen3.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5418513357438161970&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Another day, another hour. Tomorrow&#39;s a holiday!&lt;br /&gt;&lt;br /&gt;Finished the seat and the fuel tank.&lt;br /&gt;&lt;br /&gt;I realized my proportions were all wrong when I couldn&#39;t fit the fuel tank. I made the engine too big. This is one of the reasons why you should always use reference pictures when you have them.&lt;br /&gt;&lt;br /&gt;Also, it is a little funny how I put a lot of detail into the engine, even if no one will see it in the final render. Oh well.&lt;br /&gt;&lt;br /&gt;Yafaray clay render (sorry, I accidentally checked the &quot;use alpha&quot; tickbox):&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiguHLRXiP4ncuL3DcuuB52g-So2fXpI8i84RgAb13heZb23hb_bkIrGgVpUPvDM61FihETiiWWSEAGqAlJl1pihbgjuDQEtnh0WL0jJz72qbAUl4CEQWT6cLSsRqnDf_4WnorEsg7GcKAw/s1600-h/yafaray3.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 256px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiguHLRXiP4ncuL3DcuuB52g-So2fXpI8i84RgAb13heZb23hb_bkIrGgVpUPvDM61FihETiiWWSEAGqAlJl1pihbgjuDQEtnh0WL0jJz72qbAUl4CEQWT6cLSsRqnDf_4WnorEsg7GcKAw/s320/yafaray3.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5418513359017966690&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;You may have noticed how I am trying to put off modeling the chain, gears, brakes, wheels, etc. I am new to blender; this is just my fourth blender model. I am still looking for an adequate explanation/documentation on how to do spindups and how to use paths for duplication. I don&#39;t know which tool/command this is equivalent to in blender. I don&#39;t even have an idea if I&#39;m calling it right. If I don&#39;t find one, I might make my own tutorial after I figure it out.&lt;br /&gt;&lt;br /&gt;For tomorrow, the fun parts: I&#39;ll model the radiator and the exhausts plus additional engine detail.&lt;br /&gt;&lt;br /&gt;For more works, visit:&lt;br /&gt;&lt;a href=&quot;http://maranas.deviantart.com/&quot;&gt;http://maranas.deviantart.com&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/3186914309188318997/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-three.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3186914309188318997'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/3186914309188318997'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-three.html' title='[Blender] RC211v model - Day Three'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjQ8MDb9wInPlO95quPNKzC6Gtkhf8PWepAbk0yCWF7RGuPc_cp8u9r-pVZJh7fO14MfH_QNNRdlP9wXBNyxvc8Nrt66P0lz9DXTCKqT4qFkJphYLhwYatdX_SWm-UBGuoFSu02jXfhYRWw/s72-c/screen3.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-6110736135850294926</id><published>2009-12-23T01:53:00.007+08:00</published><updated>2009-12-23T03:06:06.068+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="3d"/><category scheme="http://www.blogger.com/atom/ns#" term="blender"/><title type='text'>[Blender] RC211v model - Day Two</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgVWzck9ZuOyDpia9RAolMjnM1LrGX19bLe2YcYIWcmmwPA5YZFrjBHBZHzo6KJ29memPKwDCFrSzdDSLGhvaxbbm29DSnHzsDzwfZYjUNpobmLF9jAFdWrXL10_FXjCwOvIe9npvQoEXD/s1600-h/screen2.jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 189px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgVWzck9ZuOyDpia9RAolMjnM1LrGX19bLe2YcYIWcmmwPA5YZFrjBHBZHzo6KJ29memPKwDCFrSzdDSLGhvaxbbm29DSnHzsDzwfZYjUNpobmLF9jAFdWrXL10_FXjCwOvIe9npvQoEXD/s320/screen2.jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5418120514155694866&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Day two of my modeling project. I didn&#39;t touch the model last night; today I got home late from work, and had to practice with my violin, so I only modeled for 1 hour. It is starting to look like a real bike this time. Here&#39;s a &lt;a href=&quot;http://www.yafaray.org/&quot;&gt;Yafaray&lt;/a&gt; export:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifhEJHW1dHU403fMhW0Sfo3XAFP3xktZOLu_CX4RHQXox1k3l_koHyqB1vfkXMDeT81F85_lwCbw0G5LSX94HKJB5M0mQCc6LVh666zA9M_qyZmHstTpbUgIkVSfCT1ombBLeH2N7cbFTS/s1600-h/yafray+export.png&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 256px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifhEJHW1dHU403fMhW0Sfo3XAFP3xktZOLu_CX4RHQXox1k3l_koHyqB1vfkXMDeT81F85_lwCbw0G5LSX94HKJB5M0mQCc6LVh666zA9M_qyZmHstTpbUgIkVSfCT1ombBLeH2N7cbFTS/s320/yafray+export.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5418121006084166946&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;Rendering with &lt;a href=&quot;http://www.yafaray.org/&quot;&gt;Yafaray&lt;/a&gt; has never been easier, you just need to setup your lighting in blender. Once that&#39;s done, export it to &lt;a href=&quot;http://www.yafaray.org/&quot;&gt;Yafaray&lt;/a&gt;. That&#39;s it.&lt;br /&gt;&lt;br /&gt;It is also really fast; doing a clay render takes less than 10 seconds for low-polygon models (like this one; i haven&#39;t applied the SubSurf modifiers yet) so you can easily check for modeling errors.&lt;br /&gt;&lt;br /&gt;I am getting sleepy. Hope I get some work done on it tomorrow. At least the fuel tank and seat.&lt;br /&gt;&lt;br /&gt;For other works, see:&lt;br /&gt;&lt;a href=&quot;http://maranas.deviantart.com/&quot;&gt;http://maranas.deviantart.com&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/6110736135850294926/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-two.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/6110736135850294926'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/6110736135850294926'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-two.html' title='[Blender] RC211v model - Day Two'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjgVWzck9ZuOyDpia9RAolMjnM1LrGX19bLe2YcYIWcmmwPA5YZFrjBHBZHzo6KJ29memPKwDCFrSzdDSLGhvaxbbm29DSnHzsDzwfZYjUNpobmLF9jAFdWrXL10_FXjCwOvIe9npvQoEXD/s72-c/screen2.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-5994863045850277995</id><published>2009-12-21T00:28:00.004+08:00</published><updated>2009-12-23T03:06:29.487+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="3d"/><category scheme="http://www.blogger.com/atom/ns#" term="blender"/><title type='text'>[Blender] RC211v model - Day One</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL0DMk1pPPHY2aCTWr4RnZtCg2eDJLLeMsxqbfxyZxCoCK0PRaqtcZsM-yGzK0deSIx778mypSf-_hjewm9o-5rdoxbLnz4zRsEgefC8BdCkrsmvSPQ7WTogRrCMaaSRAjtQ9uOwOz0oZn/s1600-h/motorcycle(wip).jpg&quot;&gt;&lt;img style=&quot;margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 320px; height: 190px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL0DMk1pPPHY2aCTWr4RnZtCg2eDJLLeMsxqbfxyZxCoCK0PRaqtcZsM-yGzK0deSIx778mypSf-_hjewm9o-5rdoxbLnz4zRsEgefC8BdCkrsmvSPQ7WTogRrCMaaSRAjtQ9uOwOz0oZn/s320/motorcycle(wip).jpg&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5417356623487601522&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;It has been quite sometime since I last updated my &lt;a href=&quot;http://maranas.deviantart.com&quot;&gt;deviantart&lt;/a&gt; account, and my &lt;a href=&quot;http://www.blender3d.org&quot;&gt;Blender&lt;/a&gt; skills are getting a little bit rusty, so I decided to make a model of something. Plus it&#39;s the holidays; plenty of free time and no football practice.&lt;br /&gt;&lt;br /&gt;So here is what I was able to produce: A partially modeled RC211v by Honda. I love modeling motorcycles. Maybe because this is the closest I will ever get to owning one of these babies. Plus I get to learn how they are made; much like when I&#39;m modeling cars.&lt;br /&gt;&lt;br /&gt;I plan on spending 2 hours a day into modeling random things; right now I am modeling this bike based on a &lt;a href=&quot;http://www.tamiya.com/&quot;&gt;Tamiya&lt;/a&gt; model kit I bought from Japan a few months back. No scanned-in blueprints; just straight-up modeling from real life. It is a little harder.</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/5994863045850277995/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-one.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/5994863045850277995'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/5994863045850277995'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/12/blender-rc211v-model-day-one.html' title='[Blender] RC211v model - Day One'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgL0DMk1pPPHY2aCTWr4RnZtCg2eDJLLeMsxqbfxyZxCoCK0PRaqtcZsM-yGzK0deSIx778mypSf-_hjewm9o-5rdoxbLnz4zRsEgefC8BdCkrsmvSPQ7WTogRrCMaaSRAjtQ9uOwOz0oZn/s72-c/motorcycle(wip).jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-5952322602020211820</id><published>2009-12-11T23:37:00.008+08:00</published><updated>2009-12-23T03:06:44.255+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Windows 7"/><title type='text'>Windows 7: Solution to No Internet Access (Local Only) problem</title><content type='html'>I was having problems with a &lt;a href=&quot;http://www.microsoft.com/windows/windows-7/&quot;&gt;Windows 7&lt;/a&gt; installation for a new &lt;a href=&quot;http://www.engadget.com/2008/12/17/msis-vr220-ya-edition-laptop-reviewed-average-or-just-slightl/&quot;&gt;MSI VR220&lt;/a&gt; laptop; Whenever it connects to any network, it gets Local Only access. Other computers on the network get Internet access. It gets an IP and there are no conflicts with other computers. I tried connecting wirelessly via the WiFi card and through wire via the RealTek adapter but nothing worked. I tried searching the web for answers, but to no avail.&lt;br /&gt;&lt;br /&gt;Several users suggested turning off IPv6; that wasn&#39;t the problem in my case; I was correctly getting a v6 IP from the router. Most suggested reinstalling the driver; obviously this wasn&#39;t the problem as it was able to connect and identify properly with the router. (Also,&lt;span style=&quot;font-weight: bold;&quot;&gt; any solution involving &quot;reinstallation&quot; usually means the speaker doesn&#39;t know what the problem is&lt;/span&gt;. Ask someone else.)&lt;br /&gt;&lt;br /&gt;The gateway and DNS were correctly configured; I learned this by doing an &quot;&lt;span style=&quot;font-weight: bold;&quot;&gt;ipconfig /all&lt;/span&gt;&quot; on a Vista laptop (with Internet access) connected via wifi to the same router (A TP-Link with 4 ports and wifi), and comparing the DNS and gateway IPs with the MSI Windows 7 laptop. They had the same settings.&lt;br /&gt;&lt;br /&gt;I tried diagnosing the connection by right-clicking on the adapter and clicking &quot;Diagnose&quot;; the application says that my DNS is not responding. Which is weird, because when I try pinging any website URL via command line, e.g. &lt;a href=&quot;http://www.google.com/&quot;&gt;google.com&lt;/a&gt;, I get a response. (The DNS just resolves IPs to domain names. &lt;span style=&quot;font-weight: bold;&quot;&gt;The fact that I can ping &lt;/span&gt;&lt;a style=&quot;font-weight: bold;&quot; href=&quot;http://www.google.com/&quot;&gt;google.com&lt;/a&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt; and get a response from google&#39;s IP means the DNS works&lt;/span&gt;.)&lt;br /&gt;&lt;br /&gt;By this time I was suspecting that it may be due to conflicts with a firewall/antivirus software. But this was a fresh install; no apps installed yet, and &lt;span style=&quot;font-weight: bold;&quot;&gt;used only for browsing for 2 days&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;What a difference those two days made.  When I tried logging in via user Guest, I noticed that the WiFi icon on the taskbar now tells me I have internet access. I thought the problem was solved, so I downloaded &lt;a href=&quot;http://www.avast.com/&quot;&gt;avast!&lt;/a&gt;, tried installing it as Guest. The UAC prompt appeared asking me for an Administrator user and password. I inputted the details, and when the &lt;a href=&quot;http://www.avast.com/&quot;&gt;avast!&lt;/a&gt; installer tried downloading setup files, it couldn&#39;t access the internet! &lt;span style=&quot;font-weight: bold;&quot;&gt;Applications in Guest can access the internet, but not the setup file run as Administrator&lt;/span&gt;!&lt;br /&gt;&lt;br /&gt;I switched again to the Administrator account, and tried accessing the Internet to confirm this; again the problem appears.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;At first I thought this was for security&lt;/span&gt;; maybe, just maybe, Windows 7 wouldn&#39;t let you surf the web as Administrator (which would make sense; it would be the equivalent of doing your everyday tasks in Linux as root). For the next step, I tried creating a new Administrator user. I logged in to that account, and voila, it was also able to connect to the net.&lt;br /&gt;&lt;br /&gt;The original Admin account may have been corrupted; probably by malware. From the laptop&#39;s user surfing the net with it for&lt;span style=&quot;font-weight: bold;&quot;&gt; 2 days &lt;/span&gt;unprotected. What a difference those two days can make.&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;I still haven&#39;t found the exact cause of the problem, though&lt;/span&gt;. For now, I created a new Administrator account and installed the latest &lt;a href=&quot;http://www.avast.com/&quot;&gt;avast!&lt;/a&gt; into it. Then I passworded the Administrator account, created a regular user account, and haven&#39;t heard complaints since.&lt;br /&gt;&lt;br /&gt;Lesson learned? Do not connect to any network without antivirus/anti-malware software installed. End of story.</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/5952322602020211820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/12/windows-7-no-internet-access-local-only.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/5952322602020211820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/5952322602020211820'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/12/windows-7-no-internet-access-local-only.html' title='Windows 7: Solution to No Internet Access (Local Only) problem'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-8888355026974274110</id><published>2009-11-27T00:19:00.010+08:00</published><updated>2010-07-23T05:47:42.852+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="android"/><title type='text'>Android on an HTC Touch Viva (Opal)</title><content type='html'>&lt;p&gt; The thing I love most about HTC phones, and non-iPhones in general, is you can do practically anything you want with it, and if you&#39;re clever, you won&#39;t even void the warranty. I had an HTC Magician a few years back and booted it up with all kinds of Linux distros, an &lt;a href=&quot;http://www.openmoko.com/&quot;&gt;OpenMoko&lt;/a&gt; distro included, and learned a lot on programming for mobile OSes in the process.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;A few months ago I was able to boot into Linux and &lt;a href=&quot;http://www.android.com/&quot;&gt;Android &lt;/a&gt;on my HTC Touch Viva (Opal) using &lt;a href=&quot;http://sourceforge.net/apps/trac/wing-linux/wiki&quot;&gt;Wing Linux&lt;/a&gt;, but the driver in the distro wasn&#39;t working with the touchscreen, and the key mappings were off. Today, reading from &lt;a href=&quot;http://forum.xda-developers.com/showthread.php?t=462188&quot;&gt;xda-developers&lt;/a&gt; that a new release of the distro, for OMAP850 devices, was available from the &lt;a href=&quot;http://sourceforge.net/apps/trac/wing-linux/wiki&quot;&gt;sourceforge&lt;/a&gt; page, with crossed fingers, I tried installing it again.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;And what do you know? Touch screen now works! I can even call and SMS from within Android! The Wi-Fi and Bluetooth don&#39;t work, though. And the audio. But since my phone really isn&#39;t for calling, but for developing, it isn&#39;t too much of a problem.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Here are the steps I followed to make it work on the Opal:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;/span&gt;1)Download the distro from &lt;a href=&quot;http://sourceforge.net/project/platformdownload.php?group_id=253356&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;2)Extract the files from the archive. In the archive, there will be several .CAB files. You will have to choose 2 of these files to copy to your device.&lt;/p&gt;&lt;p&gt;      &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;File 1 is the one with &lt;span style=&quot;font-weight: bold;&quot;&gt;rootfs&lt;/span&gt; in it&#39;s filename. (I can&#39;t remember the filenames, but it will be obvious).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;      File 2 is the one that is specific for your device.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;3) Copy the files to your device. Install the CAB for the root filesystem first (File 1), then install the device specific CAB next (File 2)&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-weight: bold; color: rgb(255, 102, 102);&quot;&gt;&lt;blockquote&gt;IMPORTANT: Install on you SD card. Do not install in your device&#39;s flash memory.&lt;br /&gt;&lt;/blockquote&gt;&lt;/span&gt;4) Go to Programs-&gt;Wing Linux&lt;/p&gt;&lt;p&gt;5) Click on the Run button&lt;/p&gt;&lt;p&gt;6) The Haret bootloader will start booting the Angstrom Linux distro, then Android. This may take a while, so you might want to get a cup of coffee or read a good book or something.&lt;/p&gt;&lt;p&gt;    &lt;/p&gt;&lt;blockquote&gt;At certain points in the install, it will ask you for input. For the Opal, since we do not have a keyboard, you just have to wait for it to timeout. The default settings will be selected when you do not enter any input.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;7) After a few minutes, maybe 15, check back on your device. You should see a Screen calibration screen. Calibrate the screen and wait. Again.&lt;/p&gt;&lt;p&gt;8) At this point, it will show the Angstrom boot screen. After that, the Android 1.5 boot screen. Again, more waiting.&lt;/p&gt;&lt;p&gt;9) If all goes well, you should now be booted into Android.&lt;/p&gt;&lt;p&gt;    &lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;- If at some point in the install, the screen hangs and you see a blinking cursor, and you are sure you have waited long enough (or until after the screen calibration), perform a soft reset by taking out the device&#39;s battery. Try booting into Android again. In most cases, it will be successful.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    - If the above doesn&#39;t work, delete the rootfs.img file in the linux directory and boot into Wing Linux again.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-style: italic;&quot;&gt;    *It is a prerelease build, so it&#39;s not yet perfect, but the install is quite easy. You can&#39;t complain.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;10) To soft reset in android, long-press the Red button and select Power Off. This will soft-reset the device and put you back in Windows Mobile.&lt;/p&gt;&lt;p&gt;11) To install .apks (application packages for Android), copy everything to your device&#39;s storage card before booting into android. When in Android, use the AndExplorer application to copy the .apk files to your /system/app directory.&lt;/p&gt;&lt;p&gt;Additionally, Wing Linux doesn&#39;t just work for HTC&#39;s Opal; it is for OMAP850 devices, so there is a chance that it will boot up with your device if it&#39;s OMAP850. See their &lt;a href=&quot;http://sourceforge.net/apps/trac/wing-linux/wiki/Devices&quot;&gt;&quot;Device Status&quot;&lt;/a&gt; page for known working devices, or add your own.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;As always, there is a chance that you may damage your phone while doing this, so backup your data if you can&#39;t live without it. Enjoy! Screenshots to follow!&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/8888355026974274110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/11/android-on-htc-opal.html#comment-form' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/8888355026974274110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/8888355026974274110'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/11/android-on-htc-opal.html' title='Android on an HTC Touch Viva (Opal)'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-4369817568226916610</id><published>2009-11-20T07:47:00.004+08:00</published><updated>2009-12-23T03:07:21.244+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="funny"/><title type='text'>latest movie by stephenie meyer</title><content type='html'>&lt;p&gt;team edward? team jacob? &lt;b&gt;team pacquiao&lt;/b&gt;!&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://www.imagebam.com/image/d1614856780765&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://thumbnails25.imagebam.com/5679/d1614856780765.gif&quot; alt=&quot;free image host&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://www.imagebam.com/image/a717be56780766&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://thumbnails24.imagebam.com/5679/a717be56780766.gif&quot; alt=&quot;free image host&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href=&quot;http://www.imagebam.com/image/cbcffa56780767&quot; target=&quot;_blank&quot;&gt;&lt;img src=&quot;http://thumbnails24.imagebam.com/5679/cbcffa56780767.gif&quot; alt=&quot;free image host&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;p &gt;i got this from my email, so i don&#39;t know who i can attribute it to.&lt;br /&gt;&lt;br /&gt;&lt;p&gt; and why not watch the hatton knockout while you&#39;re at it?&lt;br /&gt;&lt;p&gt;&lt;object width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;param name=&quot;movie&quot; value=&quot;http://www.youtube.com/v/yNO1KuwK8d4&amp;hl=en_US&amp;fs=1&amp;&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowFullScreen&quot; value=&quot;true&quot;&gt;&lt;/param&gt;&lt;param name=&quot;allowscriptaccess&quot; value=&quot;always&quot;&gt;&lt;/param&gt;&lt;embed src=&quot;http://www.youtube.com/v/yNO1KuwK8d4&amp;hl=en_US&amp;fs=1&amp;&quot; type=&quot;application/x-shockwave-flash&quot; allowscriptaccess=&quot;always&quot; allowfullscreen=&quot;true&quot; width=&quot;425&quot; height=&quot;344&quot;&gt;&lt;/embed&gt;&lt;/object&gt;</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/4369817568226916610/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/11/latest-movie-by-stephenie-meyer.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/4369817568226916610'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/4369817568226916610'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/11/latest-movie-by-stephenie-meyer.html' title='latest movie by stephenie meyer'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-7297374150326250503</id><published>2009-08-22T02:39:00.002+08:00</published><updated>2009-12-23T03:07:53.252+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="interesting"/><title type='text'>How to make deadlines</title><content type='html'>I just came upon this great article from gamasutra: http://www.gamasutra.com/view/feature/4111/dirty_coding_tricks.php?page=4&lt;br /&gt;&lt;br /&gt;This one takes the cake, though:&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight:bold;&quot;&gt;The Programming Antihero&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;I was fresh out of college, still wet behind the ears, and about to enter the beta phase of my first professional game project -- a late-90s PC title. It had been an exciting rollercoaster ride, as projects often are. All the content was in and the game was looking good. There was one problem though: We were way over our memory budget.&lt;br /&gt;&lt;br /&gt;Since most memory was taken up by models and textures, we worked with the artists to reduce the memory footprint of the game as much as possible. We scaled down images, decimated models, and compressed textures. Sometimes we did this with the support of the artists, and sometimes over their dead bodies.&lt;br /&gt;&lt;br /&gt;We cut megabyte after megabyte, and after a few days of frantic activity, we reached a point where we felt there was nothing else we could do. Unless we cut some major content, there was no way we could free up any more memory. Exhausted, we evaluated our current memory usage. We were still 1.5 MB over the memory limit!&lt;br /&gt;&lt;br /&gt;At this point one of the most experienced programmers in the team, one who had survived many years of development in the &quot;good old days,&quot; decided to take matters into his own hands. He called me into his office, and we set out upon what I imagined would be another exhausting session of freeing up memory.&lt;br /&gt;&lt;br /&gt;Instead, he brought up a source file and pointed to this line:&lt;br /&gt;&lt;br /&gt;static char buffer[1024*1024*2];&lt;br /&gt;&lt;br /&gt;&quot;See this?&quot; he said. And then deleted it with a single keystroke. Done!&lt;br /&gt;&lt;br /&gt;He probably saw the horror in my eyes, so he explained to me that he had put aside those two megabytes of memory early in the development cycle. He knew from experience that it was always impossible to cut content down to memory budgets, and that many projects had come close to failing because of it. So now, as a regular practice, he always put aside a nice block of memory to free up when it&#39;s really needed.&lt;br /&gt;&lt;br /&gt;He walked out of the office and announced he had reduced the memory footprint to within budget constraints -- he was toasted as the hero of the project.&lt;br /&gt;&lt;br /&gt;As horrified as I was back then about such a &quot;barbaric&quot; practice, I have to admit that I&#39;m warming up to it. I haven&#39;t gotten into the frame of mind where I can put it to use yet, but I can see how sometimes, when you&#39;re up against the wall, having a bit of memory tucked away for a rainy day can really make a difference. Funny how time and experience changes everything.&lt;br /&gt;&lt;br /&gt;- Noel Llopis</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/7297374150326250503/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/08/how-to-make-deadlines.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/7297374150326250503'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/7297374150326250503'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/08/how-to-make-deadlines.html' title='How to make deadlines'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7578929742950054449.post-7473210278739901394</id><published>2009-04-14T00:51:00.015+08:00</published><updated>2009-06-04T02:07:05.414+08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PocketTweet"/><category scheme="http://www.blogger.com/atom/ns#" term="Twitter"/><title type='text'>PocketTweet</title><content type='html'>&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;PocketTweet&lt;/span&gt;&lt;/span&gt; is a small Windows Mobile application that lets you log-in to and update your Twitter account using an active data connection.&lt;br /&gt;&lt;br /&gt;Screenshots:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.mediafire.com/imageview.php?quickkey=mhyz0oz2imn&amp;amp;thumb=4&quot;&gt;&lt;img src=&quot;http://www.mediafire.com/imgbnc.php/03cb646d03145950d8a21be15406a0084g.jpg&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.mediafire.com/imageview.php?quickkey=zmiynlogzyy&amp;thumb=4&quot;&gt;&lt;img src=&quot;http://www.mediafire.com/imgbnc.php/dd9ea014a3cdaed549edcf0eb66fa3014g.jpg&quot; border=&quot;0&quot;&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.mediafire.com/imageview.php?quickkey=jxtmmzwwxjm&amp;amp;thumb=4&quot;&gt;&lt;img src=&quot;http://www.mediafire.com/imgbnc.php/8a6857752239da5499a79c5f7d0510c54g.jpg&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;PocketTweet version 0.1(Download Here):&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;a href=&quot;http://www.mediafire.com/?zilgxyoyyx2&quot;&gt;http://www.mediafire.com/?zilgxyoyyx2&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span&gt;&lt;br /&gt;Requirements:&lt;br /&gt;- Windows Mobile (2003 and later)&lt;br /&gt;- .NET Compact Framework 2.0&lt;br /&gt;&lt;/span&gt;&lt;span style=&quot;font-weight: bold;&quot;&gt;&lt;br /&gt;&lt;/span&gt;To Do:&lt;br /&gt;- Skinnable interface&lt;br /&gt;- Direct messaging&lt;br /&gt;- twitpic support&lt;br /&gt;- saving tweets.&lt;br /&gt;- friend view&lt;br /&gt;- replies&lt;br /&gt;- account settings</content><link rel='replies' type='application/atom+xml' href='http://omokute.blogspot.com/feeds/7473210278739901394/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://omokute.blogspot.com/2009/04/pockettweet.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/7473210278739901394'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7578929742950054449/posts/default/7473210278739901394'/><link rel='alternate' type='text/html' href='http://omokute.blogspot.com/2009/04/pockettweet.html' title='PocketTweet'/><author><name>mmm</name><uri>http://www.blogger.com/profile/05001846992705657770</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>3</thr:total></entry></feed>