<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-13053610</id><updated>2012-01-27T14:49:22.156-08:00</updated><category term='other'/><category term='linguistics'/><category term='news'/><category term='shiny'/><category term='bugs'/><category term='twitter413'/><category term='programming'/><category term='randomthoughts'/><category term='smp'/><category term='anime'/><category term='atomicfunctions'/><category term='libq'/><category term='games'/><category term='memorybarriers'/><category term='hacking'/><category term='wtf'/><category term='squishy'/><category term='computers'/><category term='reallife'/><title type='text'>Q &amp; Stuff</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default?start-index=101&amp;max-results=100'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>462</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-13053610.post-8983033661974742767</id><published>2012-01-27T14:30:00.000-08:00</published><updated>2012-01-27T14:34:41.715-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><title type='text'>R.I.P. Dorkess</title><content type='html'>&lt;a href="http://1.bp.blogspot.com/-1y3IAi115bE/TyLsiovOMGI/AAAAAAAAAOU/pDGZacZFOis/s1600/CamTest13.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 339px;" src="http://1.bp.blogspot.com/-1y3IAi115bE/TyLsiovOMGI/AAAAAAAAAOU/pDGZacZFOis/s400/CamTest13.jpg" alt="" id="BLOGGER_PHOTO_ID_5702380157999657058" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Dorkess (AKA Poguita): March 27, 1992-January 27, 2012&lt;br /&gt;&lt;br /&gt;The twins, Poguita and Ping Pong (as well as two others we didn't keep, which seemed to be from different fathers) were born at our house on March 27, 1992. Poguita (yes, that is an English/Spanish pun) was named for the distinctive white stripe on her nose.&lt;br /&gt;&lt;br /&gt;As with Slinky, I later started calling her Dorkess based on her distinctive personality. She was always extremely high strung, even for a cat. The slightest sudden noise would cause her to do her characteristic "vertical takeoff and landing" - shooting a couple feet into the air - then flee in terror, either out of the house or into a closet to hide. I used to say she never walks anywhere, she just sprints.&lt;br /&gt;&lt;br /&gt;Her dorkiness led to a wide array of memorable incidents. In one case me, my mom, and one of my friends were watching something scary on TV. At one point, my mom screamed, at which point the entire clothes hamper exploded, throwing various pieces of clothing into the air. As it turned out, Dorkess had been sleeping in it, and completely freaked out when my mom screamed.&lt;br /&gt;&lt;br /&gt;She was also an extremely finicky cat; nothing was acceptable to her unless you did it exactly how she wanted it. Perhaps she was narcissistic, as she did, after all, love staring at herself in shiny surfaces. Though she lacked the congenital metabolic problems Slinky had - and as a result was not so thin and slinky - she seemed to have some kind of a deformity on her back feet such that she was never able to fully retract her claws, resulting in a distinctive clicking as she walked on hard surfaces.&lt;br /&gt;&lt;br /&gt;As she got older, she gained another distinctive attribute. For a variety of reasons, from wanting something to letting people know she was entering the house, as well as some which were just mysterious, she would use just about every muscle in her body to howl at an unbelievable volume, which vaguely resembled a baby crying; as one friend put it the first time he heard it, "What the heck was that?". On a couple occasions she even howled so loudly that she got dogs howling along with her. One particularly interesting feature of this was that, when howling, her meows were neither identical nor random, but followed a well-established pitch contour (e.g. there was always a large drop in pitch during the third meow).&lt;br /&gt;&lt;br /&gt;Apart from a couple of serious but temporary cases where she was severely sick (and could conceivably have died), she was in fairly good health until just recently (though she certainly showed her age). She did end up going completely deaf a few years ago, but this was probably for the best, as afterwards she was much calmer and less high strung.&lt;br /&gt;&lt;br /&gt;At one point a couple years ago, she began accumulating fluid around her lungs, making it difficult to breath. This probably would have killed her, but with regular medication with Lasix (the drug) the problem essentially went away (though the Lasix did seem to be doing some harm to her kidneys and liver). We never did learn the root cause, and it's possible that's ultimately related to why she died. For one reason or another, she eventually decided that she wanted to die, and simply stopped eating. This, on top of her already weakened state due to old age, resulted in her death a week later. The ultimate reason for this choice remains unknown.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://2.bp.blogspot.com/-hp8WBcahiD8/TyLsXxq2jyI/AAAAAAAAAN8/U0NZGcln45Y/s1600/Dorkess-2.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 300px;" src="http://2.bp.blogspot.com/-hp8WBcahiD8/TyLsXxq2jyI/AAAAAAAAAN8/U0NZGcln45Y/s400/Dorkess-2.jpg" alt="" id="BLOGGER_PHOTO_ID_5702379971418689314" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;One of Dorkess' common places to sleep&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-wyeBW_OzTTc/TyLsOST6f2I/AAAAAAAAANw/OJeGUZjcegM/s1600/Dorkess-1.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 196px;" src="http://4.bp.blogspot.com/-wyeBW_OzTTc/TyLsOST6f2I/AAAAAAAAANw/OJeGUZjcegM/s400/Dorkess-1.jpg" alt="" id="BLOGGER_PHOTO_ID_5702379808382156642" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-KkO2tIqSbms/TyLsnb3mOmI/AAAAAAAAAOg/ICSTTZwnuAM/s1600/Pong-Pogue.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 292px;" src="http://4.bp.blogspot.com/-KkO2tIqSbms/TyLsnb3mOmI/AAAAAAAAAOg/ICSTTZwnuAM/s400/Pong-Pogue.jpg" alt="" id="BLOGGER_PHOTO_ID_5702380240444471906" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The twins: Dorkess (left) and Slinky (right)&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-gVl26WcEF7g/TyLscanJTiI/AAAAAAAAAOI/uNPb7BY1vz4/s1600/Slinky-and-Dorkess.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 400px; height: 301px;" src="http://3.bp.blogspot.com/-gVl26WcEF7g/TyLscanJTiI/AAAAAAAAAOI/uNPb7BY1vz4/s400/Slinky-and-Dorkess.jpg" alt="" id="BLOGGER_PHOTO_ID_5702380051128471074" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;The twins sleeping, Zen-style; best guess is that Slinky is in front, Dorkess is in back&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-LUlnVja4KLY/TyMVCAlaYuI/AAAAAAAAAOs/w-x5XoiUvHg/s1600/Dorkess-and-Me.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 280px; height: 400px;" src="http://4.bp.blogspot.com/-LUlnVja4KLY/TyMVCAlaYuI/AAAAAAAAAOs/w-x5XoiUvHg/s400/Dorkess-and-Me.jpg" alt="" id="BLOGGER_PHOTO_ID_5702424677442020066" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Me and Dorkess, 5-10 years ago&lt;br /&gt;&lt;br /&gt;Rest in peace, Dorkess.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8983033661974742767?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8983033661974742767/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8983033661974742767' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8983033661974742767'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8983033661974742767'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2012/01/rip-dorkess.html' title='R.I.P. Dorkess'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/-1y3IAi115bE/TyLsiovOMGI/AAAAAAAAAOU/pDGZacZFOis/s72-c/CamTest13.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-2667858498939719401</id><published>2011-12-30T16:35:00.000-08:00</published><updated>2011-12-30T17:45:47.883-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>Anti-Piracy for Dummies</title><content type='html'>Are you a content producer or the holder of copyright you didn't actually create? Are filthy thieving pirates downloading and uploading your content all across the web, driving your gross revenue into the negative? Fear not! Immigration and Customs Enforcement is here to help!&lt;br /&gt;&lt;br /&gt;Beginning several years ago, the &lt;a href="http://www.ice.gov/"&gt;US Immigration and Customs Enforcement&lt;/a&gt; agency, in conjunction with the &lt;a href="http://www.justice.gov/"&gt;Department of Justice&lt;/a&gt; and the &lt;a href="http://www.dhs.gov/"&gt;Department of Homeland Security&lt;/a&gt;, now handles copyright and other intellectual property enforcement through &lt;a href="http://www.ice.gov/doclib/news/library/factsheets/pdf/operation-in-our-sites.pdf"&gt;Operation In Our Sites&lt;/a&gt;. Through this program ICE has the authority to forcibly seize web sites that infringe your copyrights et al, providing critical relief for those besieged by piracy such as you. Once seized, these sites prominently display the ICE et al logos and a brief explanation that the site has been seized. As an example, observe the fate that befell &lt;a href="http://www.torrent-finder.com/"&gt;torrent-finder.com&lt;/a&gt; for the rampant theft of copyrighted works it harbored.&lt;br /&gt;&lt;br /&gt;It's a common misconception that you need to have special government connections, secret backroom deals, or incriminating evidence on politicians to request such a seizure. In fact, this is not true. Any copyright, patent, or trademark holder with a Windows computer may request such a seizure for any legitimate reason, and ICE will rapidly respond, taking the offending site offline with all due haste.&lt;br /&gt;&lt;br /&gt;To request such a seizure, simply follow these easy steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Log onto your Windows computer with an account with administrator privileges (e.g. the Administrator account)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Open the Run dialog, either through the Start menu or by pressing WINKEY+R&lt;/li&gt;&lt;li&gt;Type in &lt;span style="font-style: italic;"&gt;&lt;span style="font-weight: bold;"&gt;notepad "C:\Windows\System32\drivers\etc\hosts"&lt;/span&gt;.&lt;/span&gt; If your Windows directory is not "C:\Windows", you will need to substitute the correct path.&lt;/li&gt;&lt;li&gt;For each pirate site you wish to have seized, add the line "74.81.170.110 [site domain name]" to the bottom of the file. For example, to seize &lt;a href="http://www.techdirt.com/"&gt;TechDirt&lt;/a&gt;, a notorious site dedicated to the promotion of piracy and the suppression of the free speech of congressmen and businesses, you would add "74.81.170.110 www.techdirt.com"&lt;/li&gt;&lt;li&gt;Save the file and close Notepad&lt;/li&gt;&lt;li&gt;Wait for your request to be processed by ICE. This typically varies from a few seconds to a day or so. If the sites are still online after several days, you should probably go back and make sure you did not make any mistakes in performing the above procedure.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;That's all! Fast. Easy.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;With you and ICE working together, we can all look forward to a piracy-free tomorrow!&lt;/p&gt;&lt;p&gt;&lt;span style="font-style: italic;"&gt;This post inspired by tsavory.&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-2667858498939719401?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/2667858498939719401/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=2667858498939719401' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2667858498939719401'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2667858498939719401'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2011/12/anti-piracy-for-dummies.html' title='Anti-Piracy for Dummies'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6337336926079302709</id><published>2010-10-18T15:47:00.000-07:00</published><updated>2010-11-30T21:26:40.305-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter413'/><title type='text'>Public Service Announcement</title><content type='html'>While solar panels are dark blue, almost black, they are also reflective. This means that they will likely appear white or some other bright color, which may be a big shock (and a big aesthetic problem) if you have a dark roof and the panels are clearly visible.&lt;br /&gt;&lt;br /&gt;My parents are NOT amused.&lt;br /&gt;&lt;br /&gt;Update: Actually this is only the case when the sky is cloudy, which it was the day my parents had the panels installed. When the sky is clear they look like they do without the reflection.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6337336926079302709?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6337336926079302709/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6337336926079302709' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6337336926079302709'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6337336926079302709'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/10/public-service-announcement.html' title='Public Service Announcement'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-9129107584390272514</id><published>2010-09-21T21:34:00.000-07:00</published><updated>2010-09-21T22:03:00.438-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><title type='text'>RIP Bigg'ns</title><content type='html'>The big, old puppy&lt;br /&gt;&lt;br /&gt;June 17, 1997-September 21, 2010&lt;br /&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_9GysFr4NPa4/TJmHuC-LPoI/AAAAAAAAANE/zQkxbT3WJNo/s1600/Bigg%27ns+1+copy+2.jpg"&gt;&lt;img style="cursor: pointer; width: 226px; height: 400px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/TJmHuC-LPoI/AAAAAAAAANE/zQkxbT3WJNo/s400/Bigg%27ns+1+copy+2.jpg" alt="" id="BLOGGER_PHOTO_ID_5519592043460640386" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_9GysFr4NPa4/TJmINKbFHEI/AAAAAAAAANU/WmcqBNkThd0/s1600/Bigg%27ns+3.jpg"&gt;&lt;img style="cursor: pointer; width: 212px; height: 246px;" src="http://1.bp.blogspot.com/_9GysFr4NPa4/TJmINKbFHEI/AAAAAAAAANU/WmcqBNkThd0/s400/Bigg%27ns+3.jpg" alt="" id="BLOGGER_PHOTO_ID_5519592578036866114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_9GysFr4NPa4/TJmIEgDbf7I/AAAAAAAAANM/iGB3DPe_26A/s1600/Bigg%27ns+4.jpg"&gt;&lt;img style="cursor: pointer; width: 209px; height: 250px;" src="http://1.bp.blogspot.com/_9GysFr4NPa4/TJmIEgDbf7I/AAAAAAAAANM/iGB3DPe_26A/s400/Bigg%27ns+4.jpg" alt="" id="BLOGGER_PHOTO_ID_5519592429224427442" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_9GysFr4NPa4/TJmI6QJyKjI/AAAAAAAAANc/noVqh7FRRns/s1600/Bigg%27ns+5.jpg"&gt;&lt;img style="cursor: pointer; width: 238px; height: 250px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/TJmI6QJyKjI/AAAAAAAAANc/noVqh7FRRns/s400/Bigg%27ns+5.jpg" alt="" id="BLOGGER_PHOTO_ID_5519593352669047346" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-9129107584390272514?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/9129107584390272514/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=9129107584390272514' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/9129107584390272514'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/9129107584390272514'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/09/rip-biggns.html' title='RIP Bigg&apos;ns'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_9GysFr4NPa4/TJmHuC-LPoI/AAAAAAAAANE/zQkxbT3WJNo/s72-c/Bigg%27ns+1+copy+2.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-4276628039197163094</id><published>2010-09-08T14:03:00.001-07:00</published><updated>2010-09-08T14:21:33.949-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter413'/><title type='text'>Public Service Announcement</title><content type='html'>When you call Discover card customer service, the very first thing you have to do is enter the last 4 digits of your Discover card, last 4 digits of "your social security number", and your ZIP code. It's important to note here that "your social security number" and "your ZIP code" do NOT mean "your social security number" and "your ZIP code"; it means the social security number and ZIP code of the primary cardholder, which may or may not be you.&lt;br /&gt;&lt;br /&gt;Discover card apologizes for the inconvenience of refusing to even let you talk to a real person without providing something it specifically did not ask for.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-4276628039197163094?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/4276628039197163094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=4276628039197163094' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4276628039197163094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4276628039197163094'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/09/public-service-announcement.html' title='Public Service Announcement'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-1903071106710984991</id><published>2010-08-04T11:00:00.000-07:00</published><updated>2010-08-04T11:00:02.798-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>NWScript Stack System</title><content type='html'>Note: SW has written &lt;a href="http://www.nynaeve.net/?p=342"&gt;a new post&lt;/a&gt;, talking about NWScript in general, akin to my post yesterday (though possibly in more detail than mine; I haven't actually read it all yet).&lt;br /&gt;&lt;br /&gt;So, now we know where we are (&lt;a href="http://qstuff.blogspot.com/2010/08/nwscript.html"&gt;the NWScript system&lt;/a&gt;), and where we  need to go &lt;a href="http://qstuff.blogspot.com/2010/06/llvm.html"&gt;(LLVM &lt;/a&gt;assembly). Now, how do we get there?&lt;br /&gt;&lt;br /&gt;Well, a lot of things are simple enough, requiring only trivial use of LLVM and a parser. But after investigating the NWScript system for this purpose, I identified several areas that would be nontrivial and would require some thought and effort, which I'll discuss.&lt;br /&gt;&lt;br /&gt;The first challenge - that is, a nontrivial design issue - was the stack machine. Stack machines are easy to interpret, but harder to convert to something like LLVM assembly that uses registers (like real assembly languages) and strongly declared and typed variables (unlike real assembly languages). Stack machines use a huge number of stack locations during execution, the vast majority of them (more than 96% of them, in one sample I looked at) temporary copies that last only until the next math (or other) instruction. From the opposite perspective, it's necessary that all accesses of a single variable be mapped to the same memory location, regardless of where the variable is, relative to the top of the stack. It's even possible that multiple separate locations in the code could create a stack location that represents only a single variable, despite being created in multiple places.&lt;br /&gt;&lt;br /&gt;To illustrate these problems, a few examples:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;// var1 * 0x1E&lt;br /&gt;CPTOPSP FFFFFFEC, 0004&lt;br /&gt;CONSTI 0000001E&lt;br /&gt;MULII&lt;br /&gt;// + var2&lt;br /&gt;CPTOPSP FFFFFFEC, 0004&lt;br /&gt;ADDII&lt;br /&gt;// var3 =&lt;br /&gt;CPDOWNSP FFFFFFF0, 0004&lt;br /&gt;MOVSP FFFFFFFC&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Here, we can see two stack locations are created that do not represent variables at all, but rather temporary parameters to the MUL instruction. A third temporary that also is not a real variable is created as the return value to the MUL instruction, which is then used as a parameter to the ADD instruction along with a fourth temporary copied from a variable. Finally, a fifth temporary is created for the return value from the ADD instruction, which is copied down to a result variable and destroyed. The C code for this would be &lt;code&gt;var3 = (var1 * 0x1E) + var2;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;// if (3 == 0)&lt;br /&gt;00000045 CONSTI 00000003&lt;br /&gt;0000004B CONSTI 00000000&lt;br /&gt;00000051 EQUALII&lt;br /&gt;00000053 JZ off_00000065&lt;br /&gt;// true: var = 1&lt;br /&gt;00000059 CONSTI 00000001&lt;br /&gt;0000005F JMP off_0000006B&lt;br /&gt;// false: var = 2&lt;br /&gt;00000065 CONSTI 00000002&lt;br /&gt;0000006B&lt;br /&gt;&lt;br /&gt;&lt;/code&gt;In this second case, we have an optimized variable initialization where a stack location is created in two separate locations (depending on whether a condition is true), but is in reality only a single variable. This is from a script that has &lt;code&gt;int g_i = (3 == 0 ? 1 : 2);&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;It may also be possible to use the stack as, well, a stack, building up a variable-length list of things as they're processed in one loop, then popping them in a second loop. I can't think of a practical use for this off the top of my head (something that is both useful and couldn't be accomplished any other way), but it might be possible.&lt;br /&gt;&lt;br /&gt;So, the stack system poses challenges related to identifying variables. However, a second, less obvious problem exists, although it's not as specific to stack machines. In this case, the problem relates to functions. In NWScript, a call consists of:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Reserve a temporary slot on the stack for the return value&lt;/li&gt;&lt;li&gt;Push the parameters in reverse order&lt;/li&gt;&lt;li&gt;Call the function&lt;/li&gt;&lt;li&gt;Copy and pop the return value&lt;/li&gt;&lt;/ol&gt;As implied, the caller allocates space for the return value, and the called function must remove all parameters before return. This causes a problem for us, because we need to keep track of stack positions so that we can locate variables, and alignment of the stack would be impossible as long as we have no idea what a function call will do to the stack.&lt;br /&gt;&lt;br /&gt;The solution I came up with to this problem (as well as other problems, which I'll talk about in the future), was a two-pass system that performs analysis and intermediate code generation (intermediate code is an expanded form which deals with variable references rather than the stack, making it much easier to work with; this intermediate code would then be converted to the output code type in a third pass). The two passes could have been done in a single pass, but this would have been quite messy and needlessly memory-hungry, as opposed to the more elegant and efficient two-pass system.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;First Pass&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The first pass through the script file performs a couple tasks. It identifies functions and code flow blocks: the largest groups of instructions that execute as an atomic unit and have only a single execution path from the first to the last instruction in the block. It also determines the number of parameters and return values for each function (in NWScript, functions only have a single return value, but when the bytecode is generated, structs and other complex types are flattened to primitive types, making it look like there are multiple return values).&lt;br /&gt;&lt;br /&gt;This pass is quite simple. It proceeds by scanning through the code, beginning with the main function, parsing each instruction as it goes. The current stack pointer (but not an actual stack) is maintained from instruction to instruction. As well, a code flow graph is created by watching for branch instructions and creating new flow blocks and splitting old ones (if a branch jumps into the middle of an existing flow, that flow must be split, as it's not an atomic unit). Finally, entries for functions are created as they're encountered.&lt;br /&gt;&lt;br /&gt;The biggest trick here is dealing with function calls. The effect of other operations on the stack can be trivially calculated by decoding the instruction, but we can't step past a call instruction until we know the stack displacement. The same is true for calls to API functions, but we already know exactly what they do to the stack, as those are a closed set.&lt;br /&gt;&lt;br /&gt;What I decided to do was to use a task queue. When a new, previously unencountered function is encountered in a call, a new function entry and task queue entry corresponding to the function are created, and the current analysis task is marked as blocking on that function. Conditional branches are handled more or less the same way: a new task is created for one branch, though not blocking on anything, and analysis continues at the other branch. Whenever the current task blocks (e.g. it calls an unanalyzed function), analysis switches to the first task in the queue that is not blocking on anything, and execution continues from there.&lt;br /&gt;&lt;br /&gt;Tasks ultimately complete when a return is encountered. When that occurs, the number of parameters for the function is calculated by the difference in stack pointer from the beginning of the function to the end. The function is marked as analyzed, and any tasks blocking on the function are unblocked and may potentially continue analysis. The number of return values is determined by observing the lowest stack address written to within the function. This requires that all paths through a function be evaluated, but as the return value does not affect overall stack displacement, tasks blocking on the function may resume prior to determining the exact number of return values.&lt;br /&gt;&lt;br /&gt;While this can potentially generate a large number of blocked tasks in the queue, so long as the script does not contain a loop that has no exit path or a function that calls itself recursively without a path that returns, this is guaranteed to ultimately locate a function that can return. While functions may have multiple paths from beginning to end, and all must eventually be traversed, we need only a single path to return to know the function's displacement, resulting in unblocking of tasks waiting on that function. This discovery process cascades, and analysis of all routes through the script eventually completes.&lt;br /&gt;&lt;span style="font-size:130%;"&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Second Pass&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;After the completion of the first pass, we now know all functions, code flows, and the number of parameters and return values for each function. The second pass performs several functions:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Determine the types and locations of local and global variables and create variable objects for them&lt;/li&gt;&lt;li&gt;Determine the types of function parameters and return values&lt;/li&gt;&lt;li&gt;Generate the intermediate code&lt;/li&gt;&lt;/ul&gt;The second pass is somewhat simpler in code flow logic, but much more  complicated in terms of the amount of work done. It too operates on a  task queue system, but has no concept of blocking - the task queue  exists merely to queue up alternate paths for processing after the  current path completes. It operates locally on a function using  the code flow graphs as rails to guide analysis,  processing each function completely before moving on to the next.&lt;br /&gt;&lt;br /&gt;The code for this pass resembles a mini-interpreter (well, I suppose it is), including a stack filled with references to the variable objects at that location. A new variable object is created each time some manner of instruction pushes a variable on the stack. To make things simpler during processing and final code generation, variables are explicitly created and destroyed with  dedicated instructions in the intermediate code, unlike the implicit generation/destruction in  the bytecode.&lt;br /&gt;&lt;br /&gt;Because the stack is necessary to determine what variables individual instructions reference, functions must, as in the first pass, be executed in control flow order, rather than simply evaluating each flow in the list in random order (as we do with functions). The stack at the end of each flow is saved until analysis of the function completes, so that successor flows evaluated later can pick up the stack where the previous flow left off (and one other reason I'll explain in a second).&lt;br /&gt;&lt;br /&gt;Most of the details of the second phase relate not to the topic of this post, but to later ones. One detail worth mentioning, however, is that after all flows for a function have been evaluated, stack merging occurs. Because it's possible that a stack location might be created in two separate locations that together form a single variable (as in the example above), when multiple flows converge in a single successor flow, the stacks from each of the predecessor flows must be merged: for each offset in the stacks, the variables in each corresponding position are merged, eliminating all but one copy. Because the intermediate code representation is flexible, variable merging is trivial, and requires no modification of the intermediate code itself.&lt;br /&gt;&lt;br /&gt;However, for this and other reasons, this compiler does not, as of now, support variable use of the stack: when the stack is extended to a variable length by a loop or some such, as mentioned earlier. There is no way to generate such a structure in NWScript (the scripting language), and manually-written bytecode files are anywhere between incredibly rare and non-existent, so we thought that was a reasonable omission.&lt;br /&gt;&lt;br /&gt;One really cool thing about this system, however, is that the host program can be a hybrid of interpretation and compilation. E.g. the compilation of all scripts can be offloaded to a worker thread when a module is loaded to compile in the background, and the host program can use the interpreter for a script until compilation of that script finishes. The interpreter could also be used as a fall-back for scripts the compiler is unable to compile for one reason or another, such as those with evil stack usage.&lt;br /&gt;&lt;br /&gt;Below is an example of a random block (a flow, to be precise) of bytecode and its corresponding intermediate code. Note that the addresses differ by 0xD because the bytecode block is generated by a disassembler that includes the file header in the address:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;00005282 ACTION GetTimeHour(0010), 00&lt;br /&gt;00005287 CPTOPSP FFFFFF34, 0004&lt;br /&gt;0000528F ACTION StringToInt(00E8), 01&lt;br /&gt;00005294 ACTION GetTimeHour(0010), 00&lt;br /&gt;00005299 SUBII&lt;br /&gt;0000529B ADDII&lt;br /&gt;0000529D CPDOWNSP FFFFFF00, 0004&lt;br /&gt;000052A5 MOVSP FFFFFFFC&lt;br /&gt;000052AB CONSTI 00000000&lt;br /&gt;000052B1 CONSTI 00000000&lt;br /&gt;000052B7 CONSTI 00000000&lt;br /&gt;000052BD CPTOPSP FFFFFEF8, 0004&lt;br /&gt;000052C5 ACTION SetTime(000C), 04&lt;br /&gt;000052CA CPTOPSP FFFFFF04, 0004&lt;br /&gt;000052D2 CONSTI 00000000&lt;br /&gt;000052D8 LTII&lt;br /&gt;000052DA JZ off_00005304&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;code&gt;00005275: CREATE 01F36000 ( temp SSA int )&lt;br /&gt;00005275: ACTION 0010 (0) 01F36000 ( temp SSA int )&lt;br /&gt;0000527A: CREATE 01F36030 ( temp SSA string )&lt;br /&gt;0000527A: ASSIGN 01F36030 ( temp SSA string ), 02102C10 ( string )&lt;br /&gt;00005282: CREATE 01F36060 ( temp SSA int )&lt;br /&gt;00005282: ACTION 00E8 (1) 01F36060 ( temp SSA int ), 01F36030 ( temp SSA string )&lt;br /&gt;00005282: DELETE 01F36030 ( temp SSA string )&lt;br /&gt;00005287: CREATE 01F36090 ( temp SSA int )&lt;br /&gt;00005287: ACTION 0010 (0) 01F36090 ( temp SSA int )&lt;br /&gt;0000528C: CREATE 01F360C0 ( temp SSA int )&lt;br /&gt;0000528C: SUB    01F360C0 ( temp SSA int ), 01F36060 ( temp SSA int ), 01F36090 ( temp SSA int )&lt;br /&gt;0000528C: DELETE 01F36090 ( temp SSA int )&lt;br /&gt;0000528C: DELETE 01F36060 ( temp SSA int )&lt;br /&gt;0000528E: CREATE 01F360F0 ( temp SSA int )&lt;br /&gt;0000528E: ADD    01F360F0 ( temp SSA int ), 01F36000 ( temp SSA int ), 01F360C0 ( temp SSA int )&lt;br /&gt;0000528E: DELETE 01F360C0 ( temp SSA int )&lt;br /&gt;0000528E: DELETE 01F36000 ( temp SSA int )&lt;br /&gt;00005290: ASSIGN 02102910 ( int ), 01F360F0 ( temp SSA int )&lt;br /&gt;00005298: DELETE 01F360F0 ( temp SSA int )&lt;br /&gt;0000529E: CREATE 01F36150 ( temp SSA int )&lt;br /&gt;0000529E: ASSIGN 01F36150 ( temp SSA int ), 01F36120 ( const int )&lt;br /&gt;000052A4: CREATE 01F361B0 ( temp SSA int )&lt;br /&gt;000052A4: ASSIGN 01F361B0 ( temp SSA int ), 01F36180 ( const int )&lt;br /&gt;000052AA: CREATE 01F36210 ( temp SSA int )&lt;br /&gt;000052AA: ASSIGN 01F36210 ( temp SSA int ), 01F361E0 ( const int )&lt;br /&gt;000052B0: CREATE 01F36240 ( temp SSA int )&lt;br /&gt;000052B0: ASSIGN 01F36240 ( temp SSA int ), 02102910 ( int )&lt;br /&gt;000052B8: ACTION 000C (4) 01F36240 ( temp SSA int ), 01F36210 ( temp SSA int ), 01F361B0 ( temp SSA int ), 01F36150 ( temp SSA int )&lt;br /&gt;000052B8: DELETE 01F36240 ( temp SSA int )&lt;br /&gt;000052B8: DELETE 01F36210 ( temp SSA int )&lt;br /&gt;000052B8: DELETE 01F361B0 ( temp SSA int )&lt;br /&gt;000052B8: DELETE 01F36150 ( temp SSA int )&lt;br /&gt;000052BD: CREATE 01F36270 ( temp SSA int )&lt;br /&gt;000052BD: ASSIGN 01F36270 ( temp SSA int ), 02102910 ( int )&lt;br /&gt;000052C5: CREATE 01F362D0 ( temp SSA int )&lt;br /&gt;000052C5: ASSIGN 01F362D0 ( temp SSA int ), 01F362A0 ( const int )&lt;br /&gt;000052CB: CREATE 01F36300 ( temp SSA int )&lt;br /&gt;000052CB: LT     01F36300 ( temp SSA int ), 01F36270 ( temp SSA int ), 01F362D0 ( temp SSA int )&lt;br /&gt;000052CB: DELETE 01F362D0 ( temp SSA int )&lt;br /&gt;000052CB: DELETE 01F36270 ( temp SSA int )&lt;br /&gt;000052CD: TEST   01F36300 ( temp SSA int )&lt;br /&gt;000052CD: DELETE 01F36300 ( temp SSA int )&lt;br /&gt;000052CD: JZ     000052F7&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;And lastly, perhaps getting ahead of myself, the same segment after running it through my variable optimization pass:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;00005275: CREATE 01F36000 ( temp SSA int )&lt;br /&gt;00005275: ACTION 0010 (0) 01F36000 ( temp SSA int )&lt;br /&gt;00005282: CREATE 01F36060 ( temp SSA int )&lt;br /&gt;00005282: ACTION 00E8 (1) 01F36060 ( temp SSA int ), 02102C10 ( merged string )&lt;br /&gt;00005287: CREATE 01F36090 ( temp SSA int )&lt;br /&gt;00005287: ACTION 0010 (0) 01F36090 ( temp SSA int )&lt;br /&gt;0000528C: CREATE 01F360C0 ( temp SSA int )&lt;br /&gt;0000528C: SUB    01F360C0 ( temp SSA int ), 01F36060 ( temp SSA int ), 01F36090 ( temp SSA int )&lt;br /&gt;0000528C: DELETE 01F36090 ( temp SSA int )&lt;br /&gt;0000528C: DELETE 01F36060 ( temp SSA int )&lt;br /&gt;0000528E: ADD    02102910 ( merged int ), 01F36000 ( temp SSA int ), 01F360C0 ( temp SSA int )&lt;br /&gt;0000528E: DELETE 01F360C0 ( temp SSA int )&lt;br /&gt;0000528E: DELETE 01F36000 ( temp SSA int )&lt;br /&gt;000052B8: ACTION 000C (4) 02102910 ( merged int ), 01F361E0 ( merged const int ), 01F36180 ( merged const int ), 01F36120 ( merged const int )&lt;br /&gt;000052CB: CREATE 01F36300 ( temp SSA int )&lt;br /&gt;000052CB: LT     01F36300 ( temp SSA int ), 02102910 ( merged int ), 01F362A0 ( merged const int )&lt;br /&gt;000052CD: TEST   01F36300 ( temp SSA int )&lt;br /&gt;000052CD: DELETE 01F36300 ( temp SSA int )&lt;br /&gt;000052CD: JZ     000052F7&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;For those keeping score, that's 17 instructions in the original bytecode, 43 in the raw intermediate code (26 that are create or destroy, 9 that are assigns to temporary variables), and 19 in the optimized intermediate code (10 that are create or destroy; if that still sounds like too many, note that all of those variables will be converted to registers in LLVM).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-1903071106710984991?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/1903071106710984991/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=1903071106710984991' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1903071106710984991'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1903071106710984991'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/08/nwscript-stack-system.html' title='NWScript Stack System'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-7417966656114398309</id><published>2010-08-02T12:05:00.000-07:00</published><updated>2010-08-02T13:08:43.643-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>&amp; NWScript</title><content type='html'>The attentive might have wondered why I bothered to spend a moderate amount of timewriting about a topic I'd already moved past, which is kind of uncharacteristic of me. As I said before, I had looked at LLVM for a couple days a couple weeks prior to the corresponding blog post, then moved on (I can't recall if there was anything in between LLVM and cache-oblivious algorithms).&lt;br /&gt;&lt;br /&gt;Well, part of the reason I didn't spend too much time on LLVM was because while it's neat, I didn't have an immediate use for it. However, a few days before I wrote said post Skywing randomly came up to me and asked if I wanted to write a native code compiler for NWScript, the scripting language in NeverWinter Nights 1 and 2, for the client and server he's been writing. Suddenly I had an immediate and interesting use for LLVM.&lt;br /&gt;&lt;br /&gt;&lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/NWScript"&gt;NWScript&lt;/a&gt;  (for more information see &lt;a href="http://nwvault.ign.com/?dir=resources/scripting"&gt;this&lt;/a&gt;) is a language based on C, and supports a subset of the features. It supports only a small number of data types: int, float, string, and a number of opaque types that are more or less handles to game structures accessed solely via APIs. It also supports user-defined structures, including the built-in type vector (consisting of 3 floats), though it does not support arrays, pointers, etc. All variables and functions are strongly typed, although some game objects - those referred to with handles, such as the "object" type - may not be fully described by their scripting type. NWScript has a special kind of callback pointer called an action (a term which, confusingly, has at least two additional meanings in NWScript), which is more or less a deferred function call that may be invoked in the future - specifically, by the engine - and consists of a function pointer and the set of arguments to pass to that function (a call to an action takes no parameters from the caller itself).&lt;br /&gt;&lt;br /&gt;NWScript is compiled by the level editor into a bytecode that is interpreted by a virtual machine within the games. Like the &lt;a href="http://www.javaworld.com/javaworld/jw-09-1996/jw-09-bytecodes.html"&gt;Java&lt;/a&gt; and &lt;a href="http://csharpcomputing.com/Tutorials/Lesson8.htm"&gt;.NET&lt;/a&gt; VMs, the VM for NWScript is a &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Stack_machine"&gt;stack system&lt;/a&gt;, where a strongly-typed stack is used for opcode and function parameters and return values. Parameters to assembly instructions, as with function calls, are pushed on the top of the stack, and instructions and function calls pop the parameters and, if there is one, push the result/return value onto the top of the stack. Data down the stack is copied to the top of the stack with load operations, and copied from the top of the stack to locations further down by store operations.&lt;br /&gt;&lt;br /&gt;Unlike those VMs, however, NWScript uses a pure, integrated stack system, implementing global and local variables through the stack, as well. Global variables are accessed through instructions that load/store values at indices relative to the global variable pointer BP, which is an index into the stack. Normally, global variables are at the very bottom of the stack, pushed in a wrapper function called #globals before the script's main function is called; there are opcodes to alter BP, though this is not known to ever be used. Local variables are accessed by loads and stores relative to the top of the stack, just as with the x86 (ignoring the CPU registers). Unlike the x86, however, return addresses are not kept on the stack, but &lt;a href="http://blogs.msdn.com/b/oldnewthing/archive/2005/04/21/410397.aspx"&gt;like Itanium&lt;/a&gt; are maintained in a separate, program-inaccessible stack.&lt;br /&gt;&lt;br /&gt;Oh, and for those wondering, the Java and .NET VMs have separate mechanisms for global and local variables that do not use the stack. This is actually rather surprising - you would expect them to use the stack at least for local variables, as actual processor architectures do (when they run out of registers to assign).&lt;br /&gt;&lt;br /&gt;The following show a couple random pieces of NWScript bytecode with some comments:&lt;br /&gt;&lt;pre&gt;; Allocate int and object local variables on the stack&lt;br /&gt;0000007F 02 03                    RSADDI&lt;br /&gt;00000081 02 06                    RSADDO&lt;br /&gt;; Push parameter 0&lt;br /&gt;00000083 04 06 00000000           CONSTO 00000000&lt;br /&gt;; Call game API function&lt;br /&gt;00000089 05 00 0360 01            ACTION GetControlledCharacter(0360), 01&lt;br /&gt;; Copy return value to the object local variable&lt;br /&gt;0000008E 01 01 FFFFFFF8 0004      CPDOWNSP FFFFFFF8, 0004&lt;br /&gt;; Pop the return value&lt;br /&gt;00000096 1B 00 FFFFFFFC           MOVSP FFFFFFFC&lt;br /&gt;&lt;br /&gt;; Allocate float on stack&lt;br /&gt;00000015 02 04                    RSADDF&lt;br /&gt;; Incredibly stupid way of setting the float to 3.0f&lt;br /&gt;00000017 04 04 40400000           CONSTF 3.000000&lt;br /&gt;0000001D 01 01 FFFFFFF8 0004      CPDOWNSP FFFFFFF8, 0004&lt;br /&gt;00000025 1B 00 FFFFFFFC           MOVSP FFFFFFFC&lt;br /&gt;; Assign the current stack frame to BP&lt;br /&gt;0000002B 2A 00                    SAVEBP&lt;br /&gt;; Call main()&lt;br /&gt;0000002D 1E 00 00000010           JSR fn_0000003D&lt;br /&gt;; Restore BP to what it was before (not that it was anything)&lt;br /&gt;00000033 2B 00                    RESTOREBP&lt;br /&gt;; Clean up the global variables&lt;br /&gt;00000035 1B 00 FFFFFFFC           MOVSP FFFFFFFC&lt;br /&gt;0000003B 20 00                    RETN&lt;br /&gt;&lt;br /&gt;; Push last two parameters to FloatToString&lt;br /&gt;0000043C 04 03 00000009           CONSTI 00000009&lt;br /&gt;00000442 04 03 00000012           CONSTI 00000012&lt;br /&gt;; Divide 5.0f by 2.0f&lt;br /&gt;00000448 04 04 40A00000           CONSTF 5.000000&lt;br /&gt;0000044E 04 04 40000000           CONSTF 2.000000&lt;br /&gt;00000454 17 21                    DIVFF&lt;br /&gt;; Return value of DIVFF is the first parameter to FloatToString&lt;br /&gt;00000456 05 00 0003 03            ACTION FloatToString(0003), 03&lt;br /&gt;; Return value is second parameter to SendMessageToPC. Push first parameter.&lt;br /&gt;0000045B 04 06 00000000           CONSTO 00000000&lt;br /&gt;00000461 05 00 0176 02            ACTION SendMessageToPC(0176), 02&lt;br /&gt;&lt;/pre&gt;Stack systems - especially this one, where everything is held on the stack - make for VMs that are very simple and easy to implement, and Merlin told me in the past that they're easy to compile to native code, as well. So it's not surprising that the developers used this architecture for NWScript.&lt;br /&gt;&lt;br /&gt;You might notice that Skywing has started &lt;a href="http://www.nynaeve.net/?p=331"&gt;a series of his own&lt;/a&gt; on the project, today. I actually wrote this post several weeks ago, but was waiting until the project was done to post about it. But now that it looks like he's gonna cover it, I need to start posting or I'll end up posting after him despite starting before him.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-7417966656114398309?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/7417966656114398309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=7417966656114398309' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7417966656114398309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7417966656114398309'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/08/nwscript.html' title='&amp; NWScript'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-3440433185141526107</id><published>2010-06-28T11:04:00.000-07:00</published><updated>2010-06-28T11:06:04.178-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><category scheme='http://www.blogger.com/atom/ns#' term='twitter413'/><title type='text'></title><content type='html'>Gah, this NWScript compiler is absolutely idiotic.&lt;br /&gt;&lt;br /&gt;How to push a constant onto the stack in 4 easy steps:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;reserve a spot on the stack for the constant&lt;/li&gt;&lt;li&gt;push the constant on top of the stack&lt;/li&gt;&lt;li&gt;copy the constant to the reserved space&lt;/li&gt;&lt;li&gt;pop the top (pushed in 2) off the stack&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-3440433185141526107?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/3440433185141526107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=3440433185141526107' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3440433185141526107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3440433185141526107'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/06/gah-this-nwscript-compiler-is.html' title=''/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6281131251835790363</id><published>2010-06-27T13:20:00.000-07:00</published><updated>2010-06-27T13:20:56.139-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>&amp; LLVM</title><content type='html'>A few weeks ago - before I got into &lt;a href="http://qstuff.blogspot.com/2010/06/cache-oblivious-algorithms.html"&gt;cache-oblivious algorithms&lt;/a&gt; - I briefly had a different topic du jour. In particular, I had just learned about &lt;a href="http://llvm.org/"&gt;Low-Level Virtual Machine&lt;/a&gt;, and spent a couple days researching that.&lt;br /&gt;&lt;br /&gt;LLVM is a bit hard to explain, because the boundary around what it is is rather fuzzy. To sum it up in a noun phrase, I'd say that LLVM is a modular compilation system and virtual machine. I say "compilation system" because it doesn't really consist of an actual compiler, and there's a lot of it that is outside the definition of a compiler.&lt;br /&gt;&lt;br /&gt;The core idea is that you have a program in some programming language which is compiled into a platform and language independent intermediate format. From there, the program is translated into some machine code (whatever type is used on the machine it's being run on) at a later time, either during execution (just-in-time compiling) or prior to execution (e.g. an installer converting the application to native code when the program is installed), and executed. In that sense there's some similarity to the .NET platform and Java platform, though it isn't totally analogous to those.&lt;br /&gt;&lt;br /&gt;LLVM is a collection of modules that makes the various parts of the process possible. These components form a redundant superset of a full system, so you can choose which you want for a particular purpose and leave the rest.&lt;br /&gt;&lt;br /&gt;Going chronologically through that process, the first module in LLVM is its assembler. LLVM does not directly parse and compile any particular programming language. When creating a working compiler, you must create a language parser that processes a program and performs any language-specific optimizations. LLVM takes as its input a program in LLVM assembly plus various metadata that could be useful later in the process, and assembles them into language and platform independent LLVM intermediate bytecode. A few of the &lt;a href="http://clang.llvm.org/"&gt;open-source&lt;/a&gt; &lt;a href="http://llvm.org/docs/CommandGuide/html/llvmgcc.html"&gt;parsers&lt;/a&gt; already available for LLVM include C, C++, Objective-C, and many others; there are even &lt;a href="http://vmkit.llvm.org/"&gt;parsers&lt;/a&gt; under development that take .NET and Java bytecodes as input.&lt;br /&gt;&lt;br /&gt;The LLVM assembly language differs substantially from the Java and .NET bytecode languages, and bears some resemblance to RISC assembly languages such as MIPS and PPC. LLVM assembly consists of an infinite set of Single Static Assignment (SSA) registers; each register can be assigned only once, and a new register must be allocated for the result of every computation. However, LLVM also stores a significant amount of metadata, such as call graphs and other things at a higher level than a simple assembly language, in the bytecode (language-dependent metadata provided by the compiler is also stored for  later use by language-dependent modules, e.g. if a particular language  has a runtime environment that needs more information than just the  native code). This combination of the assembly language design and rich metadata allows the optimizer and native code generator to act much more effectively, in a language-independent manner, than if they were working on a bare assembly language. Yet they are compact enough to not be significantly larger than the equivalent native code alone.&lt;br /&gt;&lt;br /&gt;The next step in the process is global optimization. LLVM implements a substantial number of language-independent &lt;a href="http://llvm.org/docs/Passes.html"&gt;optimization algorithms&lt;/a&gt;, and compiler writers can use some or all of them as they like. Because of the metadata stored with the assembly language, LLVM is not limited to dealing simply with assembly, and the effectiveness of it's optimization algorithms resembles that of a standalone compiler (e.g. Visual C++). Even better, because optimization occurs after the entire program has been assembled, LLVM can do whole-program optimizations (known as link-time code generation in VC++ and others) that are outside the ability of simple compilers that only look at a function or a source module at a time.&lt;br /&gt;&lt;br /&gt;After optimization comes native code generation (or, alternately, you could interpret the bytecode without producing native code). This step takes the assembly and metadata that has undergone language and platform independent optimization and creates executable machine code, usually after performing platform-specific optimizations, and the code is then executed. Native code generators are language-independent, interchangeable modules invoked by LLVM and, given a program in LLVM bytecode, native code can be generated for any platform that a native code generation module exists for (x86 and PPC are a couple that are &lt;a href="http://llvm.org/docs/CodeGenerator.html#targetimpls"&gt;already supported &lt;/a&gt;with open-source implementations).&lt;br /&gt;&lt;br /&gt;Finally, LLVM provides a runtime system that allows for various runtime tasks to be performed. We'll get to the other tasks later, but one to mention here is that this runtime system allows language or platform specific runtime environments to interface with LLVM-generated native code, as well as interfacing with system or dynamic link libraries. Language-dependent metadata provided by the language compiler in the distant past is also available for use here.&lt;br /&gt;&lt;br /&gt;So, that's the basic process. However, as I've been describing the logical process and not the details, this description is much more linear than reality. As was mentioned, LLVM provides a number of modules that may be optionally used, and some are redundant. As well, there's also flexibility in how the modules interact.&lt;br /&gt;&lt;br /&gt;LLVM especially provides a great deal of flexibility in the timing of optimization and native code generation. While LLVM can be used like a normal compiler, taking in LLVM assembly and generating an executable with native code that can be directly executed on the target platform, it does not need to be. It's equally possible to store the LLVM bytecode in a platform-independent "executable" and optimize it and compile it to native code at a later point, either on execution or prior to execution. LLVM can even compile individual functions to native code the first time they are called, allowing some portions of the program to potentially never be compiled at all.&lt;br /&gt;&lt;br /&gt;Finally, LLVM also supports profiling and dynamic recompilation of a program. The LLVM runtime is capable of profiling the native code of the program at runtime, determining where the program spends most of its time, what functions are executed most often, etc. based on actual usage. It can then recompile the program from bytecode, either between executions or during idle time, using this profile data to perform optimizations based on actual usage.&lt;br /&gt;&lt;br /&gt;So, that's squishy. But why should you care? Well, a few reasons. Probably the most attractive is that you can make a full, optimizing compiler for a language that will generate native code for many platforms simply by writing a parser and LLVM assembly generator - thousands of lines of code compared to hundreds of thousands or millions (see &lt;a href="http://staff.polito.it/silvano.rivoira/HowToWriteYourOwnCompiler.htm"&gt;here&lt;/a&gt; for one example of this). Alternately, if you're designing a processor for some reason (work, school, or hobby), you can write a native code generator and instantly support all the languages parsers already exist for. And then there are some less obvious uses, such as using the metadata generated by LLVM to perform complex analysis of source code for the purpose of searching for bugs, security holes, etc.&lt;br /&gt;&lt;br /&gt;LLVM is a free open-source project that may be used in free or commercial projects, open-source or proprietary. Its largest benefactor is Apple, who uses it extensively. Other companies such as Adobe also use it in various ways. For more information, see &lt;a href="http://llvm.org/pubs/2004-01-30-CGO-LLVM.pdf"&gt;this brief summary&lt;/a&gt; of the LLVM system, and the &lt;a href="http://llvm.org/"&gt;LLVM web page&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6281131251835790363?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6281131251835790363/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6281131251835790363' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6281131251835790363'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6281131251835790363'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/06/llvm.html' title='&amp; LLVM'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-4287289848242866412</id><published>2010-06-23T17:00:00.000-07:00</published><updated>2010-06-25T11:05:31.030-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>&amp; Cache-Oblivious Algorithms (Updated)</title><content type='html'>Hey, does anybody remember the days when I actually wrote stuff on this blog? Those were good times.&lt;br /&gt;&lt;br /&gt;Well, in case anybody actually remembers that far back, one of the things I'm known for is my topic du jour manner of self-education. I hear about some topic (or it comes up in some thought process), I research it for anywhere from a few days to a few months (however long it holds my interest), then I move on to some other topic. This week's topic du jour is &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Cache-oblivious_algorithm"&gt;cache-oblivious algorithms&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To explain what cache-oblivious algorithms are and why they're good, let's work through an example.&lt;br /&gt;&lt;br /&gt;Suppose we've got a sorted array of 2^24 32-bit values, for a total size of 64 MB, and we need to determine if it contains a given value (if not, to find the nearest values). As we know that the list is sorted, binary search is the obvious choice, as it's known to be O(log N) complexity; note also that a sorted array is effectively an &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Implicit_data_structure"&gt;implicit&lt;/a&gt; binary search tree with items stored in-order, and the binary search is just a traversal of that tree. This complexity dictates that the search will require approximately log2(2^24) = 24 comparisons, each by definition involving a memory access (obviously, as the array is stored in memory).&lt;br /&gt;&lt;br /&gt;Now consider a similar array containing 2^8 32-bit values (total size of 1 KB). According to the &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Big_O_notation"&gt;big O&lt;/a&gt;, a search through this array will take about 8 comparisons - 1/3 as many as the 2^24 array. Now, while these two numbers are accurate, they're highly misleading. By that measure, you'd expect it to take three times as long to perform the 2^24 search as the 2^8. It doesn't. In fact, the difference is well over an order of magnitude.&lt;br /&gt;&lt;br /&gt;The reason for this discrepancy is the assumption that all memory accesses are equal. This is invalidated by the existence of processor (and other) caching, where cache hits are significantly faster than cache misses, as well as &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Non-Uniform_Memory_Access"&gt;Non-Uniform Memory Architectures&lt;/a&gt;, where different memory banks have different access times for different processors. The 1 KB array can easily be held entirely in the processor's L1 cache, and in theory all accesses will be cache hits. The 64 MB array, on the other hand, can't even be held in L2 or L3 cache, so most memory accesses will be cache misses, and must go all the way to main memory.&lt;br /&gt;&lt;br /&gt;Of course, main memory isn't that extreme of an example, as it isn't &lt;span style="font-style: italic;"&gt;too&lt;/span&gt; much slower than processor cache. The real killer is when you have something (e.g. a database) that can't be held entirely in memory, and must be read from disk as needed (or worse, accessed over the internet at a speed that makes hard disks look fast). Hard drives are about a million times slower than RAM, meaning that each and every disk access is an excruciating performance hit, and the internet can be an order of magnitude worse.&lt;br /&gt;&lt;br /&gt;Unsurprisingly, a massive amount of research effort over the last half a century has been in minimizing that amount that must be read from disk, especially in the class of cache-aware algorithms. Cache-aware algorithms are algorithms that are tuned (typically parametrized) for a specific system configuration (e.g. cache size) to achieve performance superior to algorithms that don't take such configuration into consideration.&lt;br /&gt;&lt;br /&gt;One of the most common cache-aware algorithms, used in most file systems and database structures, is the &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/B-tree"&gt;B-tree&lt;/a&gt; (and family members), an upside-down (non-binary) search tree designed to minimize the number of disk accesses in searching data sets too large to fit entirely into memory. The B-tree is cache-aware because the block size can be adjusted to perform optimally on a given system configuration through either abstract math or actual benchmarks, and the optimal size for one configuration may perform poorly on another configuration.&lt;br /&gt;&lt;br /&gt;Surprisingly, only in the last decade have people seriously investigated whether it is possible to create algorithms that make optimal use of a system configuration regardless of what exactly that configuration is, with no parametrization. This type of algorithm is called cache-oblivious algorithms.&lt;br /&gt;&lt;br /&gt;Sometimes this is easy. A sequential scan of an array that does something on every element in order is cache-oblivious because it produces the provably minimum number of cache misses regardless of how the cache works. Divide and conquer algorithms that access each item in an array are also generally cache-oblivious and provably optimal because they ultimately divide enough to operate only on what's in a single cache line, regardless of what size the cache line is, before moving on to the next cache line (assuming, of course, that the size of each element is small in  relation to the size of a cache line); in other words, they have a more or less linear scanning memory access pattern.&lt;br /&gt;&lt;br /&gt;Binary search, however, is not cache-oblivious, as it's not a true divide and conquer algorithm in the sense that matters to us; specifically, it does not access all elements, and therefore does not get to take advantage of the predominant locality in the array. However, we can make a cache-oblivious implicit binary search tree by changing the ordering of items. To maximize performance, we want to lay out the nodes of the binary tree such that child nodes are as close as possible to their parents as often as possible, resulting in a minimal number of cache misses.&lt;br /&gt;&lt;br /&gt;The key here is what's called the &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Van_Emde_Boas_tree"&gt;van Emde Boas layout&lt;/a&gt; (VEB) (you can tell I use &lt;a href="https://www.eff.org/https-everywhere"&gt;HTTPS Everywhere&lt;/a&gt; because my Wikipedia links are all HTTPS). The basic idea is that the (triangular when drawn on paper) tree is divided recursively into (triangular) subtrees, with all nodes in each subtree being clustered together. This gives it a fractal structure with child and parent nodes being as close as possible to each other, maximizing cache locality during searches without needing to know the details of the cache system. A short tree in this form is shown below; below that is a comparison with trees in in-order, &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Breadth-first_search"&gt;breadth-first&lt;/a&gt; (BFS), and &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Depth-first_search"&gt;depth-first search&lt;/a&gt; (DFS):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_9GysFr4NPa4/TCKB2b8_mUI/AAAAAAAAAMs/JYe_9UwAt0Q/s1600/Emde+Boas+Layout.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 213px;" src="http://1.bp.blogspot.com/_9GysFr4NPa4/TCKB2b8_mUI/AAAAAAAAAMs/JYe_9UwAt0Q/s400/Emde+Boas+Layout.gif" alt="" id="BLOGGER_PHOTO_ID_5486090068307188034" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_9GysFr4NPa4/TCKCGQdr0nI/AAAAAAAAAM0/XoXVqCwoGuI/s1600/Binary+Tree+Layouts.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 188px;" src="http://1.bp.blogspot.com/_9GysFr4NPa4/TCKCGQdr0nI/AAAAAAAAAM0/XoXVqCwoGuI/s400/Binary+Tree+Layouts.gif" alt="" id="BLOGGER_PHOTO_ID_5486090340100985458" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It's worth noting that cache-oblivious structures may or may not be as fast/faster than the simpler forms when the entire data set is in the same level of cache (whether you're talking about L1, RAM, etc.). One of the papers (the same &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.83.6795&amp;amp;rep=rep1&amp;amp;type=pdf"&gt;one&lt;/a&gt; the images are from) examined the performance of static (non-changing) binary trees stored in in-order, BFS (an order that gives some cache locality while still being trivial to calculate child positions for), DFS, and VEB order, as well as two cache-aware search tree formats. In this experiment, the tree was stored in memory and cached in the processor cache - cache hits stay in the processor, cache misses go to main memory.&lt;br /&gt;&lt;br /&gt;In the case of VEB, the complex fractal structure makes it nontrivial to calculate the position of a node's children in the array. As a result, when the entire data structure is in cache, calculation of child position takes longer than memory accesses, and VEB is about 40% slower than the standard in-order ordering. VEB begins to outperform in-order ordering once about half of the tree does not fit into cache; this calculation complexity problem can be overcome by storing child pointers with each node, but this is rather self-defeating, as this only multiplies the amount of data that has to be fit into the limited cache. In almost all cases, the cache-aware algorithms were superior to the others, but obviously require tuning to the particular cache, which is exactly what we're trying to avoid. BFS also performed admirably, always at least 15% faster than in-order ordering, and superior to VEB when more than ~1.5% of the data was able to fit into cache.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://queue.acm.org/detail.cfm?id=1814327"&gt;Another article&lt;/a&gt; compared a cache-oblivious binary heap based on VEB ordering with a &lt;a href="https://secure.wikimedia.org/wikipedia/en/wiki/Binary_heap"&gt;standard binary heap using BFS ordering&lt;/a&gt;, in the context of a real-world internet page cache in actual use. Here, the heap is stored on (solid state) disk and cached in memory - cache hits go to memory while cache misses go to the disk. As in the previous benchmark, VEB performed 30% worse than the standard BFS when the entire tree could be stored in cache, but outperformed BFS when more than 0.2% of the tree was not stored in memory (I would guess this threshold is so low due to the many order of magnitude difference between memory and disk performance). At the other end, VEB peaked at 10x the speed of BFS when most of the tree was not cached. I imagine the reason this wasn't much higher was that in this real-world benchmark the priority queue was very small relative to the other data that is being accessed, and as such performance was dominated by other operations.&lt;br /&gt;&lt;br /&gt;In the ~10 years researchers have been working on this, an array of cache-oblivious algorithms have been described, such as searching, sorting, linked lists, heaps, matrix multiplication and transposition, and various geometric algorithms such as 3D bounding volumes. The list of stuff I've seen so far (though not necessarily read through completely) is shown below, though I'm certain there are other things out there as well.&lt;br /&gt;&lt;br /&gt;&lt;span class="status-body"&gt;&lt;span class="status-content"&gt;&lt;span class="entry-content"&gt;&lt;a href="http://bit.ly/9u5V7D"&gt;Cache-Efficient Layouts of Bounding Volume  Hierarchies&lt;/a&gt; [and space partitioning]&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.compgeom.com/co-chap/chap.pdf"&gt;Cache-Oblivious Algorithms&lt;/a&gt; (overview and survey)&lt;br /&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.95.1230&amp;amp;rep=rep1&amp;amp;type=pdf"&gt;Cache-Oblivious Algorithms and Data Structures&lt;/a&gt; (overview and survey)&lt;br /&gt;&lt;span class="status-body"&gt;&lt;span class="status-content"&gt;&lt;span class="entry-content"&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.7.112&amp;amp;rep=rep1&amp;amp;type=pdf"&gt;Cache Oblivious Distribution Sweeping&lt;/a&gt; (sorting and various geometric algorithms)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.68.4708&amp;amp;rep=rep1&amp;amp;type=pdf"&gt;&lt;span class="status-body"&gt;&lt;span class="status-content"&gt;&lt;span class="entry-content"&gt;Cache-Oblivious Dynamic Search Trees&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://erikdemaine.org/papers/BufferTrees_STOC2002/paper.pdf"&gt;Cache-Oblivious Priority Queue and Graph Algorithm Applications&lt;/a&gt;&lt;br /&gt;&lt;span class="status-body"&gt;&lt;span class="status-content"&gt;&lt;span class="entry-content"&gt;&lt;a href="http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.83.6795&amp;amp;rep=rep1&amp;amp;type=pdf"&gt;Cache Oblivious Search Trees via Binary Trees of  Small Height&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="status-body"&gt;&lt;span class="status-content"&gt;&lt;span class="entry-content"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;a href="http://queue.acm.org/detail.cfm?id=1814327"&gt;You're Doing It Wrong&lt;/a&gt; (overview and heap algorithm applied to a real-life internet cache program)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-4287289848242866412?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/4287289848242866412/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=4287289848242866412' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4287289848242866412'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4287289848242866412'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/06/cache-oblivious-algorithms.html' title='&amp; Cache-Oblivious Algorithms (Updated)'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_9GysFr4NPa4/TCKB2b8_mUI/AAAAAAAAAMs/JYe_9UwAt0Q/s72-c/Emde+Boas+Layout.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-7016418502365308245</id><published>2010-05-25T13:15:00.000-07:00</published><updated>2010-05-25T14:34:20.404-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><title type='text'>When Size Matters</title><content type='html'>I and another person, who is an IT professional, spent some time this weekend doing some volunteer work at a charity - more specifically, a homeless shelter and rehabilitation clinic, though any more details information isn't particularly relevant. Our task was to do "computer stuff", including basic maintenance on all their computers (those in the administration offices and those for use by residents), as well as take a look at what they had in storage.&lt;br /&gt;&lt;br /&gt;While the computers available to residents weren't bad (about 5 years old or less), the situation in the office was more grim. Almost all of the computers were Pentium 3s and 4s, most with 256 megs of RAM and running Windows 2000 with Internet Explorer 6. That's right, Windows 2000 and IE6, which are both several years past end of life, and thus inherently insecure; oh, and did I mention that all the office staff run with admin privileges?&lt;br /&gt;&lt;br /&gt;So, we started off with the easy stuff: chkdsk (full disk surface scan) and defrag on all of them. We intended to run virus scans on all of them, but were repeatedly thwarted by bad CD-ROM drives and stupid video cards that prevented us from using the AV boot disks I'd burned for the occasion (as I didn't trust the computers to not have rootkits), and eventually we had to resort on many computers to just running the AV from inside Windows.&lt;br /&gt;&lt;br /&gt;While there were a few more specific problems with the computers, one universal complaint among the office staff was that the computers were anywhere from slow to extremely slow. While defrag no doubt helped a little with that (the computers were between 5 and 40% fragmented), the primary problem appeared to be something else entirely. Most of the computers had 256 megs of RAM, and on boot most of them were using anywhere from 210 to 260 megs of memory; add in 20 megs of memory for IE (I wanted to switch them to Firefox or a newer version of IE, but as both of those used significantly more memory that wasn't really an option), 30-40 megs for an Office app or two, and the observation that Windows starts disk-thrashing when you get to about 85% of physical memory used (about 220 megs), and it was clear that the computers were severely disk-thrashing.&lt;br /&gt;&lt;br /&gt;So, memory upgrades were the obvious prescription. But that raises the question: why were the computers using so much memory to begin with? Anyone who remembers back from the day 10 years ago, including both myself and the other guy, can tell you that 256 megs should be plenty for Windows 2000 (and perhaps even XP). Given all the available evidence - that the computers ran Windows 2000 and IE6 in admin mode, our inability to do a proper virus scan on most of them, and the fact that there was a lot of unaccounted for memory (memory that was in use but not accounted for by running processes or kernel allocations) - naturally we assumed that they were severely infested with malware.&lt;br /&gt;&lt;br /&gt;As irony would have it, the cause was actually just the opposite. On Sunday I finally got fed up with the situation, and decided to try a drastic experiment inspired with some experience in the past: I uninstalled the &lt;a href="http://free.avg.com/ww-en/download-avg-anti-virus-free"&gt;AVG Free&lt;/a&gt; antivirus that was on most of the computers. This experiment paid off; it turns out that AVG was in fact using a full 130 megs of memory. Without it, Windows was using about 80 megs of memory at boot, which is very much like what we remembered back from the day, when virus scanners took 30-40 megs, which would leave about 110 of the 256 megs available for running applications comfortably.&lt;br /&gt;&lt;br /&gt;So... now what? Well, another 256 megs memory would put an end to the problem. But in the mean time, I had a stop-gap measure: get a smaller AV. Out of my previous tests on the &lt;a href="http://arstechnica.com/security/news/2009/09/av-comparatives-picks-seven-anti-malware-winners.ars"&gt;best of the free AVs&lt;/a&gt;, the best current-generation AV in this regard was &lt;a href="http://download.cnet.com/Avira-AntiVir-Personal-Free-Antivirus/3000-2239_4-10322935.html"&gt;Avira AntiVir Personal&lt;/a&gt;, weighing in at about 95 megs. So, I switched all of the computers over to that. This reduced the amount of memory in use at boot to about 180 megs, leaving about 40 megs available for comfortably running applications. While that isn't a huge amount, I'm hoping that in a case this severe it will substantially improve performance until more memory can be acquired cheaply.&lt;br /&gt;&lt;br /&gt;On that topic, I actually ordered a batch of used and very cheap 256 meg sticks off eBay, and I'm hoping to be able to test them out (which will take a couple days to thoroughly test this quantity of sticks) and get them installed this weekend or next, bringing the computers up to 512 megs; assuming, of course, that these computers (most of them Dells) aren't of the extremely finicky variety that reject all but very closely-matched memory. At 512 megs, it becomes reasonable to start looking at upgrading the computers to XP (pretty sure it wouldn't be a good idea to try Vista on those computers) and Firefox, which would go a long way to improving security (and, of course, at that point it would be worth making them not run as admin).&lt;br /&gt;&lt;br /&gt;On one last note, one thing that continues to stump both of us is how on one computer the fonts in IE are enormous. On typical web pages lines of text are often 1-1.5 inches tall, making it extremely difficult to use the web. We both independently looked at both font settings and accessibility features in both IE and Windows, but none of those proved to be the cause. Setting fonts to smallest in IE made text more reasonable, but on some pages the text was actually "smallest", making it impossibly small to read; thus this was not a sufficient solution to the problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-7016418502365308245?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/7016418502365308245/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=7016418502365308245' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7016418502365308245'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7016418502365308245'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/05/when-size-matters.html' title='When Size Matters'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-7141511304431792321</id><published>2010-05-04T12:25:00.001-07:00</published><updated>2010-05-04T12:31:55.954-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><title type='text'>What the</title><content type='html'>This one was a bit too long to post on Twitter. A quote from a &lt;a href="http://arstechnica.com/tech-policy/news/2010/05/court-rapidshare-doesnt-need-to-filter-uploads.ars"&gt;link&lt;/a&gt; I tweeted:&lt;br /&gt;&lt;blockquote&gt;In addition, the appeals court took aim at several filtering schemes.  Blocking all files of a certain type (such as RAR files) was deemed  inappropriate, since a file type has no bearing on the legality of an  upload. Scanning by IP address was also tossed, because numerous people  can use a single IP address. File name filtering tells you nothing about  the contents of a file, so that was tossed. Even content scanning was  problematic, as the court noted that this would just lead to encrypted  files. Besides, even if you could know that a file was copyrighted, it  could still be a legal "private backup" not distributed to anyone else.&lt;/blockquote&gt;&lt;br /&gt;Courts making rulings based on actual technical knowledge? What's this world coming to? I note that they even &lt;a href="http://qstuff.blogspot.com/2010/02/content-filtering.html"&gt;listened to me&lt;/a&gt; (okay, probably just other people with similar technical knowledge) and realized that content scanning would be ineffective as it would just lead to ubiquitous encryption with no actual reduction in infringement.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-7141511304431792321?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/7141511304431792321/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=7141511304431792321' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7141511304431792321'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7141511304431792321'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/05/what.html' title='What the'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6818203396690053660</id><published>2010-05-03T15:40:00.000-07:00</published><updated>2010-05-03T15:42:19.970-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>&amp; Twitter</title><content type='html'>Okay, I replaced the Twitter gadget from Blogger with the official Twitter one. It doesn't really visually match the blog, but all the ones that were available on Blogger had the same problem with links. This one doesn't.&lt;br /&gt;&lt;br /&gt;Let me know if somebody knows one that matches visually without this problem.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6818203396690053660?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6818203396690053660/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6818203396690053660' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6818203396690053660'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6818203396690053660'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/05/twitter.html' title='&amp; Twitter'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-5636590260282035820</id><published>2010-05-03T15:13:00.000-07:00</published><updated>2010-05-03T15:15:50.365-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>&amp; Bugs</title><content type='html'>Yikes. Somebody just made me aware that if you follow one of the links posted in my tweets on the sidebar, it opens the link in that little tweet frame. That's very buggy. I'll have to see if I can get Blogger (the one that created the Twitter thing) to fix that.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-5636590260282035820?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/5636590260282035820/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=5636590260282035820' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5636590260282035820'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5636590260282035820'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/05/bugs.html' title='&amp; Bugs'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-1156020376340955010</id><published>2010-04-30T15:30:00.000-07:00</published><updated>2010-04-30T15:30:13.842-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>&amp; Domain-Specific Computing</title><content type='html'>So, I went to the public lecture at UCI today (the one I posted an event for on my Facebook page). These public lectures are by various guest speakers on a wide range of  topics; each one is usually something of an overview of a particular field, often ones which the average computer science student has minimal or no exposure to in their classes. As with last time, there were free brownies and coffee/tea.&lt;br /&gt;&lt;br /&gt;Note that this post is all from memory. I didn't take notes or anything, so there are likely to be omissions and vagueness compared to the actual lecture.&lt;br /&gt;&lt;br /&gt;The topic this time was domain-specific computing. Essentially this refers to the use of some manner of special-purpose hardware to offload work from a general-purpose CPU, either eliminating the CPU entirely or allowing the use of a smaller, cheaper, and more efficient CPU. The ultimate purpose of this is to reduce overall cost and power consumption while increasing overall performance for a given task.&lt;br /&gt;&lt;br /&gt;If this doesn't sound revolutionary, it's because it's not. Modular electronics have been around for as long as electronics in total. If you want a real-world example of something built this way, you can look at just about anything at all. Computers consist of many components (e.g. motherboard, video card), each composed of many further components (GPU, southbridge, northbridge, etc.), usually microchips.&lt;br /&gt;&lt;br /&gt;The problem then is that it's hard to manufacture these chips. It's expensive, requires skill in engineering, and is largely done manually. Skilled electrical engineers must manually design a circuit, then a huge fabrication plant uses big and very expensive machines to manufacture the circuit, which is then available for use in various devices. Because of the expense and manufacturing requirements, most companies  are not able to produce custom chips in this way.&lt;br /&gt;&lt;br /&gt;As a result, very common specialized circuits are produced and sold off-the-shelf in large quantities, while less general circuits instead use  code running on a general-purpose CPU. After chip design and fabrication, another electric engineer must then analyze everything a particular device must do, determine where it would be beneficial to use specialized off-the-shelf components (which may either be used directly or require some manner of mapping to make the data fit the exact component), then determine which CPU to use for everything else, and have the programmers write the code for it.&lt;br /&gt;&lt;br /&gt;Done correctly, the resulting device is faster, cheaper to manufacture, and more efficient than simply using a fast CPU to do everything. One of the papers he cited examined different algorithms implemented on a general-purpose CPU, a general-purpose GPU, and a custom &lt;a href="http://en.wikipedia.org/wiki/Field-programmable_gate_array"&gt;FPGA&lt;/a&gt; (chips that can be programmed without massive fabrication plants, but  are less efficient than standard fabricated chips). For one algorithm (seemingly a highly parallel one), the GPU performed 93x as well as the CPU, and the FPGA 11x. While the GPU was 8x as fast as the FPGA in absolute terms (though presumably you could increase the size of the FPGA 8 times, to match the GPU's total performance), when you compare performance:power consumption, the GPU was 60x that of the CPU, and the FPGA was about 220x: about 3.5x the performance of the GPU (and I'd wager the FPGA cost less than either of them). In other algorithms, the difference was tens of thousands of times.&lt;br /&gt;&lt;br /&gt;But it's still a whole lot of work. Consequently, this tends to be done for mass-produced electronic devices, while more specialized things are simply executed on a common computer, as it's cheaper to code a program than engineer an electrical device.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://cadlab.cs.ucla.edu/%7Econg/"&gt;This guy&lt;/a&gt; (the one who gave the lecture) is working to develop analysis and automation tools to reduce the cost and difficulty of custom hardware development, to significantly increase the range of things that are viable to produce this way. Ideally, you'd be able to write a specification or algorithm (e.g. a C++ program that describes an entire device's function), then automation would analyze the system, performing these steps (essentially the same ones I summarized above):&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Break it down into major functional units&lt;/li&gt;&lt;li&gt;Determine which units can use off-the-shelf components and what the optimal component is&lt;/li&gt;&lt;li&gt;Locate algorithms that would substantially benefit from the production of new components and then design those components for manufacturing, either using FPGAs, circuit boards, or as actual fabricated chips&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Choose the optimal CPU and algorithm for the tasks remaining (that aren't worth implementing in hardware) and write the code. Remember that different tasks run better or worse on different CPU architectures, so this step must find the best CPU for the given algorithm or rewrite the algorithm in a way that runs better on a more preferable (e.g. cheaper) CPU. For example, CPUs that lack branch prediction are cheaper and more energy-efficient, but perform poorly on algorithms that use a great deal of branching; however, depending on the task to be performed, an alternate algorithm might be able to perform the task with less branching.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Design an optimal bus architecture for all the different electronic to communicate&lt;/li&gt;&lt;/ol&gt;Of course, it's very likely that this ideal is fundamentally impossible - at least until artificial intelligence is able to perform as well as a skilled electrical engineer. However, he hopes to create tools that drastically reduce the amount of human time and cost needed for this process, and the talk was about recent research toward that goal. A few of the automation problems under research by different groups:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Identification of identical algorithm matches to existing circuits as well as partial matches that can work with some amount of data conversion&lt;/li&gt;&lt;li&gt;Profiling of different matching circuits to determine which performs optimally on a given problem&lt;/li&gt;&lt;li&gt;Determination of which algorithms would perform substantially better if implemented in custom hardware&lt;/li&gt;&lt;li&gt;Conversion of procedures (e.g. C++ programs) to electronic schematics for manufacturing&lt;/li&gt;&lt;li&gt;Profiling of different CPU architectures (e.g. x86 and ARM), models (e.g. i5 and i7), and variants (e.g. cache size, with or without optional subunits, etc.), to determine which is optimal for a given device, based on performance and cost&lt;/li&gt;&lt;li&gt;Profiling of different bus architectures (e.g. mesh and crossbar) and configurations (e.g. number and size of channels) to determine what is optimal for a device&lt;/li&gt;&lt;li&gt;Modularization for energy efficiency, to allow entire circuits to be shut off when they aren't in use (but others are)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;I don't remember too much more detail than what I've already said. One last point is that this guy seemed to be a big fan of the multiband radio-frequency interconnect (RF-I) bus for the purpose of inter-component communication. This works essentially the same as the radio or broadcast TV, where bandwidth is split into separate channels, each with a different range of modulation frequencies. As this allows bandwidth to be arbitrarily allocated between many bus channels (and may even be configured in real time), this is very amenable to communication and power optimization.&lt;br /&gt;&lt;br /&gt;Actually, it looks like &lt;a href="http://cadlab.cs.ucla.edu/%7Econg/slides/fpl09_keynote.pdf"&gt;the slides&lt;/a&gt; from the lecture are available online for you to look at, beyond what I've already written about it.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-1156020376340955010?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/1156020376340955010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=1156020376340955010' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1156020376340955010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1156020376340955010'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/04/domain-specific-computing.html' title='&amp; Domain-Specific Computing'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-7343921240504156397</id><published>2010-04-16T18:31:00.000-07:00</published><updated>2010-04-16T18:31:58.879-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>&amp; MPQDraft and StarCraft 2</title><content type='html'>In the course of randomly wasting time today, I decided to go look at how &lt;a href="http://sourceforge.net/projects/mpqdraft/"&gt;MPQDraft&lt;/a&gt; is doing in terms of popularity, these days. I do that every so often, but it had been a few months since I last looked.&lt;br /&gt;&lt;br /&gt;To my surprise, I noted a substantial spike in downloads: 50% more binary downloads and 100% more source downloads, beginning in February. It took me a second to realize the likely cause: SC2 going into beta mid-February. It's not clear to me whether people expect MPQDraft to work with SC2, or whether SC2 has inspired a more general revival in modding.&lt;br /&gt;&lt;br /&gt;In any case - MPQDraft does not work with the SC2 beta. There are two reasons for this.&lt;br /&gt;&lt;br /&gt;Part of why MPQDraft is so elegant is that it works in a game- and version-independent manner. This is possible because MPQDraft intercepts function calls between the games and the Storm DLL, the latter which contains the functions to access MPQs. This only works if Storm is dynamically linked to the game, in its own DLL. The SC2 beta statically links to Storm; the MPQ functions, as well as others, are incorporated directly into the game executable.&lt;br /&gt;&lt;br /&gt;This means the current simple, elegant MPQDraft method will not work, period. The only way to deal with this problem, and to make MPQDraft work when the game statically links to Storm, is to directly locate the function addresses in the game, and include those addresses themselves in the MPQDraft DLL.&lt;br /&gt;&lt;br /&gt;The problem with this is that it's game- and version-dependent. Every time a new patch comes out you'll have to wait until I or somebody else updates the function addresses before you can use MPQDraft on the new version. And this obviously requires somebody taking the time to manually locate the functions in every new version, from scratch.&lt;br /&gt;&lt;br /&gt;So, that's in the "pain in the ass" class of problems. It also remains to be seen whether Blizzard intends to ship SC2 linked in this way,  or if it will dynamically link to Storm in the release version.&lt;br /&gt;&lt;br /&gt;The bigger problem is the fact that SC2 is online most of the time, including when you're playing single player (unless you specifically tell it to run in offline mode). Depending on how aggressively Blizzard performs its anti-cheating scans (which they've been doing since SC1), it's plausible that MPQDraft could be detected as a cheat, in which case you'd probably get your account banned.&lt;br /&gt;&lt;br /&gt;That's the current state of MPQDraft and SC2.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-7343921240504156397?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/7343921240504156397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=7343921240504156397' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7343921240504156397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7343921240504156397'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/04/mpqdraft-and-starcraft-2.html' title='&amp; MPQDraft and StarCraft 2'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-946005249923047707</id><published>2010-04-11T15:40:00.000-07:00</published><updated>2010-04-16T19:58:06.242-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><title type='text'>&amp; Twitter</title><content type='html'>On a tangentially-related note, I've also joined  Twitter. This one I have a very specific purpose for: link spam (the stuff I formerly sent to friends on IM services and pasted into chat room).  A place where I can simply link to interesting, funny, or otherwise linkable stuff I find online, without giving any commentary, and I can post stuff too insignificant or off-topic to clutter this blog with (although I may occasionally post short random thoughts, as well).&lt;br /&gt;&lt;br /&gt;Those of you who think this blog has had entirely too little computer/programming stuff on it lately should check out my &lt;a href="https://twitter.com/JustinOlbrantz"&gt;Twitter feed&lt;/a&gt;. While these days most of the stuff I think long and hard about (and blog about) is linguistics, the majority of the stuff I read online remains about computers, video games, and programming. So, expect the majority of my tweets to be on those topics, like this blog was, back before I became interested in linguistics.&lt;br /&gt;&lt;br /&gt;There are several ways you can access my tweets. If you're on Twitter, you can simply follow me. If you're not, you can either see the mini-Twitter feed now on the blog sidebar, read the Twitter tab of my FaceBook page, or subscribe to the &lt;a href="http://twitter.com/statuses/user_timeline/131962216.rss"&gt;RSS version&lt;/a&gt; of my Twitter feed.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-946005249923047707?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/946005249923047707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=946005249923047707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/946005249923047707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/946005249923047707'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/04/twitter.html' title='&amp; Twitter'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-3366783971584694323</id><published>2010-04-11T13:32:00.000-07:00</published><updated>2010-04-11T13:42:22.801-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><title type='text'>&amp; Facebook</title><content type='html'>So, I joined &lt;a href="http://www.facebook.com/profile.php?id=100000990514575"&gt;Facebook&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Not much to say about it. It was purely for practical reasons (because an organization I'm with apparently now uses Facebook to communicate with their members with regard to things like meeting dates), so I'm not planning on doing too much with it. I'll take a look at the features and we'll see. If I can find a use for some part of it (that I actually care to use) I might use it for that; if not I'll just use it as a friend hub and one more way to find me on the internet.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-3366783971584694323?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/3366783971584694323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=3366783971584694323' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3366783971584694323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3366783971584694323'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/04/facebook.html' title='&amp; Facebook'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-3265475081343200073</id><published>2010-04-03T12:49:00.000-07:00</published><updated>2010-04-03T12:51:00.989-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='anime'/><title type='text'>&amp; Spring Anime Thoughts</title><content type='html'>Sooooo, exactly how much of that &lt;a href="http://qstuff.blogspot.com/2010/04/new-endeavors.html"&gt;last post&lt;/a&gt; was real, and how much was April Fools? About half of it. RaptorIIC did indeed talk to me about the idea of making an anime blog, and the idea has come up again (and more seriously) with Random Curiosity closing. It's not true that we've actually (yet) decided to go for it, and the ecchi/hentai theme is definitely not true, either. And, ironically, the day after I wrote that post, RC &lt;a href="http://randomc.animeblogger.net/2010/04/02/update-your-bookmarks/"&gt;announced&lt;/a&gt; that it might not be closing after all.&lt;br /&gt;&lt;br /&gt;So, moving back into the real world, in this post I'll discuss some of the new series I might &lt;span style="font-style: italic;"&gt;actually &lt;/span&gt;watch, this season. Of course this is all very tentative, as not even one episode of most of these have aired yet. What's more, many of them really fall into a "I'll take a look at it and see how it is" category, which isn't particularly informative. Again, the series summaries and pictures are coming from RC and THAT (although in this post they'll be quoted, so you can differentiate the summary from my own comments).&lt;br /&gt;&lt;blockquote&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/maidsama.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/maidsama.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;div class="preview_info"&gt;&lt;b&gt;Kaichou wa Maid-sama!&lt;/b&gt; | 会長はメイド様！&lt;br /&gt;&lt;a href="http://www.tbs.co.jp/anime/maidsama/" target="_blank"&gt;&lt;/a&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=11037" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, &lt;a href="http://www.animenfo.com/animetitle,4652,pseuuo,kaicho_wa_maid_.html" target="_blank"&gt;AnimeNfo&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=7008" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/7054/Kaichou_wa_Maid-sama%21" target="_blank"&gt;MyAnimeList&lt;/a&gt;, &lt;a href="http://cal.syoboi.jp/tid/1890/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; After only reading a glimpse of the premise  and taking a look at the art style, I was already convinced that “The  Student Council President is a Maid!” was my kind of show.  Reading a  bit of the shoujo manga only reaffirmed that thought, as it has  everything I’d want in a romantic comedy.  The story focuses on a girl  who’s enrolled in an all-boys school that has recently turned co-ed, and  worked her ass off to become the student council president so that she  can change the bad habits in the still predominantly male school.  She  develops a tough exterior as a result and doesn’t particularly like men  because of how her father walked out on her and her family, but works a  part-time job at a maid cafe to make ends meet.  The most popular guy in  school stumbles onto her secret one day and she thinks she’s set up for  a huge embarrassment, but he chooses to keep it a secret because he’s  unknowingly infatuated with her.&lt;/blockquote&gt;I'm not so sure about that picture, but the description sounds like it could be entertaining, and slice-of-life comedies (optionally with romance) are my bread and butter in anime, after all. The first episode aired last night (covered by both &lt;a href="http://randomc.net/2010/04/01/kaichou-wa-maid-sama-01/"&gt;RC&lt;/a&gt; and &lt;a href="http://www.thatanimeblog.com/index.php/2010/04/kaichou-wa-maid-sama-review-hate-love-and-happiness/"&gt;THAT&lt;/a&gt;), and one of the (very) fast but good subbing groups already had it out, so I got a chance to see it. So far it looks pretty good, although you can't always count on the first episode of something being representative of a series, as the first episode usually forms the background of the main story.&lt;br /&gt;&lt;br /&gt;The premise of the series is very much like the "so &lt;a href="http://en.wikipedia.org/wiki/Moe_%28slang%29"&gt;moe&lt;/a&gt; I am gonna die" [what it actually got tagged on AniDB at one point] &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=5581"&gt;Nogizaka Haruka's Secret&lt;/a&gt;. So far this one doesn't seem as horrific as that series; perhaps this is due to this being a girls' series and that one being an ecchi guys' series, though shoujo series can (potentially) be horrific in their own way. This hasn't been the case in the first episode, but the first episode is pre-romance, which is where things could go downhill.&lt;br /&gt;&lt;br /&gt;So, I'll definitely watch some more and see how it goes.&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/angelbeats.jpg"&gt;&lt;/a&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="preview_info"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/angelbeats.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/angelbeats.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Angel Beats!&lt;/b&gt; | エンジェルビーツ!&lt;br /&gt;&lt;a href="http://www.angelbeats.jp/" target="_blank"&gt;&lt;/a&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=10885" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, &lt;a href="http://www.animenfo.com/animetitle,4656,otwnzu,angel_beats_.html" target="_blank"&gt;AnimeNfo&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6564" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/6547/Angel_Beats%21" target="_blank"&gt;MyAnimeList&lt;/a&gt;,  &lt;a href="http://cal.syoboi.jp/tid/1896/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; One of the series I’m really looking forward  to and can safely recommend to all audiences is Angel Beats.  For some,  it might be enough if I just say, “&lt;a href="http://en.wikipedia.org/wiki/Key_%28company%29" target="_blank"&gt;Key&lt;/a&gt;  and &lt;a href="http://en.wikipedia.org/wiki/P.A._Works" target="_blank"&gt;P.A.  Works&lt;/a&gt;.”  For everyone else, this means the visual novel company  that brought us &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=2480" target="_blank"&gt;AIR&lt;/a&gt;, &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=7809" target="_blank"&gt;CLANNAD&lt;/a&gt;, and &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=6431" target="_blank"&gt;Kanon&lt;/a&gt;, and the studio that produced &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=6257" target="_blank"&gt;true tears&lt;/a&gt; and &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=10270" target="_blank"&gt;CANAAN&lt;/a&gt;.  &lt;a href="http://www.animenewsnetwork.com/encyclopedia/people.php?id=51681" target="_blank"&gt;Maeda Jun&lt;/a&gt; from Key is writing the script and  screenplay, depicting an afterworld where one girl forms a war front,  the Shinda Sekai Sensen (SSS), in defiance to god for giving her an  unreasonable and short life.  In this supernatural afterlife setting, we  follow male protagonist Otonashi, who has no memories of when he was  alive and gets dragged into the SSS’s struggles.  Guns and superpowers  are involved, but so is a seemingly normal school life at the same time.&lt;/blockquote&gt;Key is a very well known maker of &lt;a href="http://en.wikipedia.org/wiki/Visual_novel"&gt;"dating sim"&lt;/a&gt; games. As mentioned in the summary, to date three of their games have been adapted into anime, and I've seen them all. The supernatural and fighting aspects are certainly different than any of previous ones, though it sounds as though it still has the school slice-of-life parts they're known for, as well. The three series so far have been at least enjoyable, so I'll probably end up watching this, also. It will be interesting to see how they do something less traditional dating sim.&lt;br /&gt;&lt;br /&gt;RC has covered &lt;a href="http://randomc.net/2010/04/02/angel-beats-01/"&gt;episode 1&lt;/a&gt;. It's also been subbed by a group, though I haven't seen it, yet.&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/sangokuengi.jpg"&gt;&lt;/a&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="preview_info"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/sangokuengi.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/sangokuengi.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Romance of the Three Kingdoms&lt;/b&gt; | 最強武将伝・三国演義&lt;br /&gt;&lt;a href="http://www.tv-osaka.co.jp/sangokuengi/" target="_blank"&gt;&lt;/a&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=10698" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, AnimeNfo, AniDB, &lt;a href="http://myanimelist.net/anime/6902/Sangoku_Engi" target="_blank"&gt;MyAnimeList&lt;/a&gt;,  syoboi&lt;/div&gt; And here it is, the fourth series this season  with some basis on &lt;a href="http://en.wikipedia.org/wiki/Romance_of_the_Three_Kingdoms" target="_blank"&gt;Romance of the Three Kingdoms&lt;/a&gt;, except this one’s  meant to be the real deal, or at least Chinese studio Beijing Glorious  Animation’s interpretation of it.  It’s actually a joint production with  Japan’s &lt;a href="http://en.wikipedia.org/wiki/Takara_Tomy" target="_blank"&gt;Takara Tomy&lt;/a&gt; and Future Planet (the first of its  kind) in regards to both planning and animation production.  So if you  don’t care for the pretty girls seen in Ikkitousen and Koihime Musou nor  Gundams and wanted a faithful version with old men, then here’s the  perfect alternative.  This 52-episode series was aired in China by &lt;a href="http://en.wikipedia.org/wiki/China_Central_Television" target="_blank"&gt;CCTV&lt;/a&gt; and completed its run back in 2008, meaning  this is a rebroadcasting for the Japanese market.  It took four years to  complete and cost 650 million yen (~7m USD).&lt;/blockquote&gt;Well, that isn't the most informative summary in the world. For more information, see the &lt;a href="http://en.wikipedia.org/wiki/Romance_of_the_Three_Kingdoms"&gt;Wikipedia entry&lt;/a&gt; on the original Romance of the Three Kingdoms.&lt;br /&gt;&lt;br /&gt;Basically, it's a pretty famous Chinese story (at least in that part of the world). For that reason I might check it out, although I must say that 52 episodes is a really large number for a series that may or may not be any good. One thing that could be interesting is that, as the series was produced by a Chinese company and originally aired in China, the series might be in Chinese, with Japanese subtitles.&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/working.jpg"&gt;&lt;/a&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="preview_info"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/working.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/working.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;WORKING!!&lt;/b&gt; | ワーキング!!&lt;br /&gt;&lt;a href="http://www.wagnaria.com/" target="_blank"&gt;&lt;/a&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=11017%20target=" _blank=""&gt;ANN Encyclopedia&lt;/a&gt;, &lt;a href="http://www.animenfo.com/animetitle,4664,hrsghk,working__.html" target="_blank"&gt;AnimeNfo&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6780" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/6956/Working%21%21" target="_blank"&gt;MyAnimeList&lt;/a&gt;,  &lt;a href="http://cal.syoboi.jp/tid/1885/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; If you’re looking for a cute slice-of-life  comedy with an all-star cast, then look no further than WORKING.  It’s  an easy-going series that centers on high school student Takanashi  Souta, who gets recruited by his short and absolutely adorable senior,  Taneshima Popura, to work at a Hokkaido family restaurant named Wagnaria  (&lt;i&gt;hence the official site URL&lt;/i&gt;).  As a normal and diligent 16 year  old, Souta soon learns that all his coworkers are a bit unusual.  This  includes a manager who doesn’t care to work properly, a floor chief who  carries a katana with her, and a server with &lt;a href="http://en.wikipedia.org/wiki/Androphobia" target="_blank"&gt;androphobia&lt;/a&gt;.   However, as a self-proclaimed lover of all things small and helpless  (i.e. “minicon”), Souta sticks with it and there doesn’t ever seem to be  a boring day at his job.  The first episode of this had a special early  broadcast last month, and I found it a perfect fit to fill that quirky  yet clean humor slot for the season. &lt;/blockquote&gt;That's about as slice-of-life comedy as you can get. This one actually had an early airing of the first episode a few weeks ago, and it wasn't bad. So, I'm planning on watching it. Oddly, neither RC nor THAT did a summary of the first episode to link you to, despite it being out for a couple weeks.&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/arakawa_ub.jpg"&gt;&lt;/a&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="preview_info"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/arakawa_ub.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/arakawa_ub.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Arakawa Under the Bridge&lt;/b&gt; | 荒川アンダー ザ ブリッジ&lt;br /&gt;&lt;a href="http://www.starchild.co.jp/special/arakawa_ub/" target="_blank"&gt;&lt;/a&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=11188" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, &lt;a href="http://www.animenfo.com/animetitle,4643,qthnvy,arakawa_under_t.html" target="_blank"&gt;AnimeNfo&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=7238" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/7647/Arakawa_Under_the_Bridge" target="_blank"&gt;MyAnimeList&lt;/a&gt;, &lt;a href="http://cal.syoboi.jp/tid/1898/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; This is an adaptation of Nakamura Hikaru’s  gag/romantic comedy manga about a young man named Ichinomiya Kou who  sits on top of the business world, and whose family motto is to never be  in debt to anyone for anything.  He has that so ingrained in his mind  since birth that the mere thought of having debts gives him an asthmatic  panic attack.  One day by Arakawa Bridge, he’s saved by a homeless girl  named Nino living below, leaving him with the biggest debt ever.  He’s  completely unable to cope with the thought of that and tries to repay  Nino by buying her a house, but she’s a bit odd and asks him to love her  instead.  Thus begins Kou’s life under the bridge with her, where he  meets a bunch of very strange individuals, including the resident &lt;a href="http://www.starchild.co.jp/special/arakawa_ub/character/soncho.html" target="_blank"&gt;Kappa village chief&lt;/a&gt;.  From the manga, I found the  character interactions reminiscent of &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=10196" target="_blank"&gt;Bakemonogatari&lt;/a&gt;, mainly because Kou doesn’t know how  to deal with the calm, composed, and most of all weird Nino.&lt;/blockquote&gt;Another one for the "definitely maybe" pile. On the one hand the art and premise just screams "chick flick" (it is a girls' series, after all), though the premise also seems a bit intriguing. Bakemonogatari was pretty good, so if it's like Bakemonogatari, it could be good; we'll have to see how similar they really are.&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/rainbow.jpg"&gt;&lt;/a&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="preview_info"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/rainbow.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/rainbow.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;RAINBOW Nisha Rokubou no Shichinin&lt;/b&gt; | RAINBOW 二舎六房の七人&lt;br /&gt;&lt;a href="http://www.ntv.co.jp/rainbow/" target="_blank"&gt;&lt;/a&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=9700" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, &lt;a href="http://www.animenfo.com/animetitle,4423,ljpcqr,rainbow_nisha_r.html" target="_blank"&gt;AnimeNfo&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=7389" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/6114/Rainbow" target="_blank"&gt;MyAnimeList&lt;/a&gt;,  &lt;a href="http://cal.syoboi.jp/tid/1915/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; If you’re looking for a show that’s very  different from the usual stuff, then consider this adaptation of Abe  George (Jouji) and Kakizaki Masumi’s award-winning manga.  Taking place  in 1955 after the end of World War II, it depicts the hardships that six  juvenile delinquents go through after getting thrown into a corrections  facility/prison, often graphically so.  From everything to getting  sexually abused by the male doctor and having to deal with the tyranny  of the wardens, it’s meant to be a realistic view on poverty-stricken  Japan following the war.  Upon arrival to the prison, the six boys are  thrown into Block 2 Cell 6 where they meet “Anchan”, their senior inmate  who shows them some tough love on how to survive.  The story follows  the lives of these seven, both in prison and afterward.  Abe George  described this as a “story about friendship and courage”, which I could  get a sense of from the first few chapters of the manga.  Each of the  boys was sentenced for acts of assault and theft, but the circumstances  they committed their crimes under don’t necessarily make them bad kids,  and you can get a feel for that from the bonds they make. &lt;/blockquote&gt;Another maybe series. From that description, it sounds like it could be interesting, if it doesn't turn out to be too depressing. I tend to dislike series that are dark and depressing, so we'll see how it turns out.&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/k_on.jpg"&gt;&lt;/a&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="preview_info"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/k_on.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/k_on.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;K-ON!!&lt;/b&gt; | けいおん!!&lt;br /&gt;&lt;a href="http://www.tbs.co.jp/anime/k-on/" target="_blank"&gt;&lt;/a&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=11262" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, &lt;a href="http://www.animenfo.com/animetitle,4689,dcxbal,k_on__.html" target="_blank"&gt;AnimeNfo&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=7307" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/7791/K-ON%21%21" target="_blank"&gt;MyAnimeList&lt;/a&gt;,  &lt;a href="http://cal.syoboi.jp/tid/1882/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; &lt;div class="preview_text"&gt;It was only at the end of last year that K-ON  season two was &lt;a href="http://randomc.animeblogger.net/2009/12/31/k-on-second-season-greenlit/" target="_blank"&gt;announced&lt;/a&gt;, but three months later we already have  more of our favorite light music club.  Now with one more exclamation  mark in the title!  The extra DVD/BD &lt;a href="http://randomc.animeblogger.net/2010/01/18/k-on-ova/" target="_blank"&gt;live house episode&lt;/a&gt; helped tide things over a bit,  but it’s not quite the same as a full season where we’re bound to hear a  bunch of new songs.  For those unfamiliar with this series, it’s &lt;a href="http://en.wikipedia.org/wiki/Kyoto_Animation" target="_blank"&gt;Kyoto  Animation&lt;/a&gt;’s adaptation of a lighthearted &lt;a href="http://en.wikipedia.org/wiki/Yonkoma" target="_blank"&gt;4-koma manga&lt;/a&gt;  that follows a group of girls who revive their high school’s music club  by forming a band called “After School Tea Time”.   It’s published in a  &lt;a href="http://en.wikipedia.org/wiki/Manga_Time_Kirara" target="_blank"&gt;seinen manga magazine&lt;/a&gt; and features quirky humor and a  very cute cast of female characters.  In short, it’s &lt;a href="http://en.wikipedia.org/wiki/Moe_%28slang%29" target="_blank"&gt;moe&lt;/a&gt;  overload.  When the original season aired last spring, the cast of  seiyuus were all relatively low-profile, but that all changed with this  series.  The opening and ending theme songs they sang debuted at #4 and  #2 on the &lt;a href="http://en.wikipedia.org/wiki/Oricon" target="_blank"&gt;Oricon&lt;/a&gt;  music charts respectively, and they’ve all been in numerous series now,  especially lead actress &lt;a href="http://www.animenewsnetwork.com/encyclopedia/people.php?id=62870" target="_blank"&gt;Toyosaki Aki&lt;/a&gt;.  There are &lt;a href="http://www.tbs.co.jp/anime/k-on/onair/onair.html" target="_blank"&gt;28  broadcast stations&lt;/a&gt; lined up to air this highly anticipated sequel,  which absolutely dwarfs every other series by a long shot.  There’s no  doubt in my mind that I’ll be watching this and it’s a safe series to  recommend to almost anyone.  Go watch the first season now if you  haven’t!&lt;/div&gt;&lt;/blockquote&gt;&lt;div class="preview_text"&gt;&lt;/div&gt;...and the infamous moe blob returns. To summarize it in a sentence, it's a slice-of-life school comedy about excessively moe girls doing excessively moe things, especially writing/performing excessively moe songs in their amateur band (the premise of the series). It's "the definition of moe" [what it got tagged on AniDB]: if you love moe, you'll probably love it; if you hate moe, you'll probably hate it.&lt;br /&gt;&lt;br /&gt;I watched the &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6257"&gt;first season&lt;/a&gt; of this, a couple seasons ago (I mentioned that it had a good ending song). It was fairly enjoyable, although it really had entirely too much moe; though obviously the guy who wrote the summary disagrees with that assessment. In either case, it's decently amusing, even if it can get on your nerves.&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/goyou.jpg"&gt;&lt;/a&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="preview_info"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/goyou.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/goyou.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Saraiya Goyou&lt;/b&gt; | さらい屋 五葉&lt;br /&gt;&lt;a href="http://www.goyou-anime.jp/" target="_blank"&gt;&lt;/a&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=11176" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, &lt;a href="http://www.animenfo.com/animetitle,4679,vvcuek,saraiya_goyo.html" target="_blank"&gt;AnimeNfo&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=7248" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/7588/Saraiya_Goyou" target="_blank"&gt;MyAnimeList&lt;/a&gt;,  &lt;a href="http://cal.syoboi.jp/tid/1887/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; The &lt;a href="http://en.wikipedia.org/wiki/Noitamina" target="_blank"&gt;noitaminA&lt;/a&gt;  time slot has expanded from half an hour to a full hour this season,  and taking the bottom slot is an adaptation of &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=10449" target="_blank"&gt;Ristorante Paradiso&lt;/a&gt; creator Ono Natsume’s “House of  Five Leaves”.  It takes place during the &lt;a href="http://en.wikipedia.org/wiki/Edo_period" target="_blank"&gt;Edo  period&lt;/a&gt; and revolves around a timid &lt;a href="http://en.wikipedia.org/wiki/R%C5%8Dnin" target="_blank"&gt;rounin&lt;/a&gt;  named Akitsu Masanosuke.  By chance, he runs into a charismatic  individual that wants to hire him as his bodyguard but later finds out  that he’s the leader of a gang known as the Five Leaves.  Realizing what  he’s up against, Masanosuke gets wrapped up in the gang and its very  unique individuals and learns there’s more to them than it initially  seems.  Don’t be swayed by the character designs here if they seem a bit  odd to you, as this is just Natsume’s unique style.  Personally, I find  they’re a refreshing change from the more generic ones you often see.&lt;/blockquote&gt;This one's a big question mark. It sounds like it could potentially be interesting, but that's a pretty big maybe. I watched the first couple episodes of &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6384"&gt;Ristorante Paradiso&lt;/a&gt; and couldn't stand it, between the art and the writing. So, we'll find out in a week or two how this one is.&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/yojouhan.jpg"&gt;&lt;/a&gt;&lt;/div&gt;&lt;blockquote&gt;&lt;div class="preview_info"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/yojouhan.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/yojouhan.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Yojou-han Shinwa Taikei&lt;/b&gt; | 四畳半神話大系&lt;br /&gt;&lt;a href="http://yojouhan.noitamina.tv/" target="_blank"&gt;&lt;/a&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=11200" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, &lt;a href="http://www.animenfo.com/animetitle,4653,jylldc,yojohan_shinwa_.html" target="_blank"&gt;AnimeNfo&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=7243" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/7785/Yojouhan_Shinwa_Taikei" target="_blank"&gt;MyAnimeList&lt;/a&gt;, &lt;a href="http://cal.syoboi.jp/tid/1867/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; Taking the top slot in &lt;a href="http://en.wikipedia.org/wiki/Noitamina" target="_blank"&gt;noitaminA&lt;/a&gt;’s  newly expanded time slot is a novel adaptation about a nameless  third-year Kyoto University student (&lt;i&gt;only referred to as “I”&lt;/i&gt;) and  his life with the “Tennis Circle Cupid” club that he joined in his  first year.  The story is broken up into four chapters and will be aired  as an 11 episode series here.  Not having read the novel, I’m not too  sure what to expect, but the promo videos already showcase how strangely  different everything is.  The title on the other hand seems to  translate to “Compendium of 4½ &lt;a href="http://en.wikipedia.org/wiki/Tatami" target="_blank"&gt;Tatami&lt;/a&gt;  Mythology”.&lt;/blockquote&gt;Another big question mark, and this one is even less clear on what it's going to be like. Though I have to say the art kind of gives me a bad feeling. Either way, we'll again know more in a couple weeks.&lt;br /&gt;&lt;br /&gt;Oh, and in case anyone happens to be interested, RC has covered &lt;a href="http://randomc.net/2010/04/02/b-gata-h-kei-01/"&gt;B Gata H Kei 1&lt;/a&gt; (mentioned yesterday).&lt;br /&gt;&lt;br /&gt;On a final note, both the Currently Watching section and the &lt;a href="http://qstuff.blogspot.com/2009/08/introduction-to-anime.html"&gt;Introduction to Anime/List&lt;/a&gt; (which includes a list of almost all free-to-watch anime series I've seen) link on the sidebar are still live, and being updated as new series come out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-3265475081343200073?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/3265475081343200073/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=3265475081343200073' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3265475081343200073'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3265475081343200073'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/04/spring-anime-thoughts.html' title='&amp; Spring Anime Thoughts'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-5803848623174821319</id><published>2010-04-01T18:04:00.000-07:00</published><updated>2010-04-01T18:20:12.507-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='anime'/><title type='text'>&amp; New Endeavors</title><content type='html'>A ways back, RaptorIIC, one of the modders back from the StarCraft era, came to me with an idea. He was considering starting an anime blogging site with some of his friends, and wondered if I'd be interested. The basic idea is that bloggers write summaries of episodes of certain series (the ones they're watching) each time a new episode comes out; readers then read the summaries and discuss each episode via the posts' comments. In the past I've mentioned two such sites that I follow: &lt;a href="http://randomc.animeblogger.net/"&gt;Random Curiosity&lt;/a&gt; (henceforth known as RC) and &lt;a href="http://www.thatanimeblog.com/"&gt;T.H.A.T. Anime Blog&lt;/a&gt; (although the latter is mainly for a second set of opinions on new season series, in addition to RC).&lt;br /&gt;&lt;br /&gt;I gave it some serious consideration, and mentioned it to a number of my friends online, though I don't think I ever mentioned it on this blog. However, nothing ever became of the idea, and for quite a while nobody thought about it again.&lt;br /&gt;&lt;br /&gt;However, now that RC is &lt;a href="http://randomc.animeblogger.net/2010/03/22/all-good-things/"&gt;closing its doors&lt;/a&gt;, the idea has come up again, and more seriously than before. To make a long story short, we decided to give it a shot, and just applied to &lt;a href="http://www.animeblogger.net/"&gt;AnimeBlogger&lt;/a&gt; (the host of RC, and I believe at one time the host of THAT). As is typical for AnimeBlogger (as mentioned in their &lt;a href="http://www.animemaestro.com/archives/ab-blog-hosting"&gt;FAQ&lt;/a&gt;), it's taking a few days to get the new blog all set up.&lt;br /&gt;&lt;br /&gt;However, despite this being inspired by the closure of RC, our blog is a bit more of a niche market. That is, our blog will specialize in &lt;a href="http://en.wikipedia.org/wiki/Ecchi"&gt;ecchi&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Hentai"&gt;hentai&lt;/a&gt; series.&lt;br /&gt;&lt;br /&gt;Coming up with a name wasn't exactly trivial. We wanted something halfway tasteful, yet still had a halfway appropriate meaning. "Q &amp;amp; H" was immediately rejected for being too cheesy. Ultimately we decided on Zettai Ryouiki [from &lt;a href="http://www.csse.monash.edu.au/%7Ejwb/cgi-bin/wwwjdic.cgi?1C"&gt;WWWJDIC&lt;/a&gt;: "&lt;span style="font-size:1px;"&gt;絶対領域: &lt;/span&gt;exposed skin  between top of knee-high socks and hemline of skirt (lit: absolute  territory)"].&lt;br /&gt;&lt;br /&gt;As you might know, this is right in time for the spring anime season, which begins next week. Obviously we won't know exactly what we're going to cover until we can actually see an episode or two of the new series, but here are a couple that look like good candidates for blogging (the information and pictures are ripped from &lt;a href="http://randomc.animeblogger.net/2010/03/28/spring-2010-preview/"&gt;RC's&lt;/a&gt; and &lt;a href="http://www.thatanimeblog.com/index.php/2010/03/t-h-a-t-spring-2010-anime-preview/"&gt;THAT's&lt;/a&gt; season previews from a few weeks ago; note thus that any first-person statements are not mine):&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/bgata_hkei.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/bgata_hkei.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;B Gata H Kei&lt;/b&gt; | B型H系&lt;br /&gt;&lt;a href="http://www.bgata-hkei.com/" target="_blank"&gt;http://www.bgata-hkei.com/&lt;/a&gt;&lt;br /&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=11199" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, AnimeNfo, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=7286" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/7817/B_Gata_H_Kei" target="_blank"&gt;MyAnimeList&lt;/a&gt;,  &lt;a href="http://cal.syoboi.jp/tid/1886/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; Adapted from a &lt;a href="http://en.wikipedia.org/wiki/Yonkoma" target="_blank"&gt;4-koma manga&lt;/a&gt;  serialized in &lt;a href="http://en.wikipedia.org/wiki/Weekly_Young_Jump" target="_blank"&gt;Weekly Young Jump&lt;/a&gt;, B Gata H Kei (&lt;i&gt;B-type H-style&lt;/i&gt;)  targets an &lt;a href="http://en.wikipedia.org/wiki/Seinen_manga" target="_blank"&gt;older audience&lt;/a&gt; with a story about a beautiful high  school girl named Yamada, whose sex-ridden mind wants to sleep with 100  different guys.  Despite her beauty, she’s actually a virgin because  she’s too worried about being ridiculed by good-looking and experienced  sex partners to lose it.  One day, she mistakenly believes that a plain  and homely guy named Kosuda Takashi intentionally saved her from falling  over in a bookstore.  Sensing that he’s a good yet  sexually-inexperienced man like she’s been looking for, she decides to  use him as her first and craziness ensues.&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.thatanimeblog.com/wp-content/uploads/2010/02/kiss-sis.jpg"&gt;&lt;img style="cursor: pointer; width: 225px; height: 329px;" src="http://www.thatanimeblog.com/wp-content/uploads/2010/02/kiss-sis.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;kiss x sis&lt;/b&gt; | キスシス&lt;br /&gt;&lt;a href="http://www.starchild.co.jp/special/kiss_sis/" target="_blank"&gt;http://www.starchild.co.jp/special/kiss_sis/&lt;/a&gt;&lt;br /&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=11169" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, &lt;a href="http://www.animenfo.com/animetitle,4651,fslysf,kiss_x_sis_tv.html" target="_blank"&gt;AnimeNfo&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=7215" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/7593/Kiss_x_Sis_%28TV%29" target="_blank"&gt;MyAnimeList&lt;/a&gt;, &lt;a href="http://cal.syoboi.jp/tid/1904/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; Ecchi fans rejoice, as the seinen manga turned  OVA is getting its own TV series.  Studio &lt;a href="http://en.wikipedia.org/wiki/Feel_%28company%29" target="_blank"&gt;Feel&lt;/a&gt;  is producing this retelling as well, and it will be broadcast on AT-X (&lt;i&gt;and  only AT-X&lt;/i&gt;).  I don’t think I’ll ever quite understand the Japanese  fantasy/fetish over incest, but kiss x sis revolves around that idea  with stepsiblings unrelated by blood.  This is probably the most  risqué/borderline hentai series in this season’s lineup, involving a  middle school boy named Suminoe Keita, whose high school twin  stepsisters, Ako and Riko, are passionately in love with him and will  seduce and violate him every chance they get.  Keita however doesn’t  want any involvement with them in that way and tries to focus on getting  into the same high school, even though their parents encourage a  potential relationship.  The girls completely drive the explicit  fan-service here, with Ako being a closet pervert and Riko calm and  assertive, but there &lt;i&gt;is&lt;/i&gt; some plot involving their childhoods to  tie things together in a meaningful way.  This still doesn’t change the  fact that sexual scenarios are foremost, so unsuspecting viewers beware.&lt;br /&gt;&lt;br /&gt;&lt;div class="preview_info"&gt; &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/ikkitousenxx.jpg"&gt;&lt;img style="cursor: pointer; width: 250px; height: 300px;" src="http://randomc.dreamhosters.com/image/Miscellaneous/Spring%202010%20Preview/ikkitousenxx.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;b&gt;Ikkitousen XTREME XECUTOR&lt;/b&gt; | 一騎当千 XTREME XECUTOR&lt;br /&gt;&lt;a href="http://www.ikkitousen.com/" target="_blank"&gt;http://www.ikkitousen.com/&lt;/a&gt;&lt;br /&gt;Information Links: &lt;a href="http://www.animenewsnetwork.com/encyclopedia/anime.php?id=11177" target="_blank"&gt;ANN Encyclopedia&lt;/a&gt;, &lt;a href="http://www.animenfo.com/animetitle,4649,ivwwcg,ikkitosen_xtrem.html" target="_blank"&gt;AnimeNfo&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=7219" target="_blank"&gt;AniDB&lt;/a&gt;, &lt;a href="http://myanimelist.net/anime/7580/Ikkitousen:_Xtreme_Xecutor" target="_blank"&gt;MyAnimeList&lt;/a&gt;, &lt;a href="http://cal.syoboi.jp/tid/1872/time?Filter=ChUser&amp;amp;Filter2=All" target="_blank"&gt;syoboi&lt;/a&gt;&lt;/div&gt; I gather Ikkitousen doesn’t need too much  introduction, seeing as XTREME XECUTOR marks the fourth season of the  series, but the story here is &lt;i&gt;loosely based&lt;/i&gt; on the classic  Chinese novel &lt;a href="http://en.wikipedia.org/wiki/Romance_of_the_Three_Kingdoms" target="_blank"&gt;Romance of the Three Kingdoms&lt;/a&gt;.  That’s what they  advertise it as anyway, but anyone who’s actually watched the show will  probably tell you it’s an overflowing fan-service affair with busty  girls from rival schools fighting one another and getting their clothes  torn off like there’s no tomorrow.&lt;br /&gt;&lt;br /&gt;On the downside, being an anime blogger will require a lot less laziness from me, as I'll have to blog each episode as it comes out (once a week, for however many series). And everybody knows I hate obligations.&lt;br /&gt;&lt;br /&gt;I'll let you know when the blog is online.&lt;br /&gt;&lt;br /&gt;Oh, and entirely coincidentally, &lt;a href="http://www.animenewsnetwork.com/"&gt;Anime News Network&lt;/a&gt; currently has an ad theme that seems very relevant to this announcement. The relevant slice of the theme:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.animenewsnetwork.com/stylesheets/negima2/skin_header.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 85px;" src="http://www.animenewsnetwork.com/stylesheets/negima2/skin_header.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-5803848623174821319?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/5803848623174821319/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=5803848623174821319' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5803848623174821319'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5803848623174821319'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/04/new-endeavors.html' title='&amp; New Endeavors'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6064561141052416036</id><published>2010-03-28T14:36:00.000-07:00</published><updated>2010-03-28T14:40:19.115-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>&amp; StarCraft 2</title><content type='html'>I really should have posted this weeks ago, but IskatuMesk (user mancatcher, on YouTube) has being doing a &lt;a href="http://www.youtube.com/profile?user=mancatcher#g/u"&gt;series of YouTube posts&lt;/a&gt; of SC2 games with commentary. Many of the replays are in 1080 high-definition, although I only watch the 480 resolution versions, as that's all my 1.5 Mbps DSL can support in real-time, and it's okay, clarity-wise. I've been watching just about everything he's posted since he started covering it.&lt;br /&gt;&lt;br /&gt;The vast majority of them are of high or mid/high-level players. A lot of them are games (usually free-for-alls) he plays in, himself. He's in the platinum league (currently the highest, with gold, silver, bronze, and copper below), which puts him in the mid/high skill category. Others, however, are commentaries on replays of really famous SC1 pro players, frequently obtained from &lt;a href="http://www.teamliquid.net/"&gt;Team Liquid&lt;/a&gt;'s forum.&lt;br /&gt;&lt;br /&gt;On one or two occasions you see him getting in-game messages from me (some of which make absolutely no sense, like when I was testing out what the mature language filter blocks - e.g. "XonX" and "came" - which he had disabled). One replay, however, is a 2on2 I actually played. Now, I'm in the silver league, so this is not exactly a replay displaying master strategy (and I get my ass handed to me by Mesk's commentary of the match, which is kind of amusing in its own way). It does, however, have an absolutely hilarious ending, as indicated by the &lt;a href="http://www.youtube.com/comment_servlet?all_comments&amp;amp;v=5zKsfdLyNKI&amp;amp;fromurl=/watch%3Fv%3D5zKsfdLyNKI"&gt;stuff&lt;/a&gt; people have said about it (e.g. "&lt;span class="content"&gt;oh god im﻿ dying over here", "&lt;/span&gt;&lt;span class="content"&gt;Holy shit. I teared up at the end there", "&lt;/span&gt;&lt;span class="content"&gt;dear god that﻿ was amazing", "&lt;/span&gt;&lt;span class="content"&gt;Most hilarious﻿ ending evar"&lt;/span&gt;&lt;span class="content"&gt;). Amusingly, this replay has proven his most popular, and has almost 3x as many views as almost all of the other replays of the same age; I wonder if it got posted on a forum with a couple thousand users, somewhere.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=WDnlxBPwZfI"&gt;Part 1&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.youtube.com/watch?v=5zKsfdLyNKI"&gt;Part 2&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Oh, and since the ending is kind of ambiguous: my team won.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6064561141052416036?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6064561141052416036/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6064561141052416036' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6064561141052416036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6064561141052416036'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/03/starcraft-2.html' title='&amp; StarCraft 2'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-5369309956949911158</id><published>2010-03-22T18:09:00.000-07:00</published><updated>2010-03-22T18:14:38.353-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linguistics'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><category scheme='http://www.blogger.com/atom/ns#' term='anime'/><title type='text'>Q's Squishy Thing of the Day</title><content type='html'>One of the manga series I've been waiting forever for an English translation of (to buy, that is; fan-translated versions have been around online for years) is &lt;a href="http://en.wikipedia.org/wiki/Elfen_Lied"&gt;Elfen Lied&lt;/a&gt;, which I &lt;a href="http://qstuff.blogspot.com/2005/07/infatuation.html"&gt;mentioned being fond of&lt;/a&gt; in the past. Well, there's still not official English translation, but I just learned something very interesting: there's an &lt;a href="http://www.mundovid.com/buscador.asp?busqueda=Elfen+Lied&amp;amp;tipo_busq=7"&gt;official Spanish version&lt;/a&gt; (also &lt;a href="http://www.tokyopop.de/buecher/manga/elfen_lied/index.php"&gt;German&lt;/a&gt; and &lt;a href="http://www.egmanga.com.tw/"&gt;Taiwanese Chinese&lt;/a&gt;, for speakers of those languages). So I can own the series I've wanted for a long time, while practicing my Spanish.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://qstuff.blogspot.com/2008/02/mother-load.html"&gt;I mentioned a ways back&lt;/a&gt; that I was reading the Spanish version of the Trique grammar book (as there wasn't an equivalent English version), and I was surprised how well I could read the Spanish, without even looking things up. However, a part of the reason this went so smoothly was that most of the unknown words in that were linguistic jargon that I was able to figure out from context very quickly.&lt;br /&gt;&lt;br /&gt;Actually, &lt;a href="http://qstuff.blogspot.com/2007/07/trique.html"&gt;my very first exposure to Trique&lt;/a&gt;, prior to that, also involved Spanish. It all began with a Spanish/Trique bilingual Bible I got from my grandpa. I started by comparing the text in Spanish and Trique to attempt to figure out the grammar by example. This was somewhat more difficult than the grammar book. It had a much broader array of words used, so it was significantly harder to figure out unknown words from context. Still, I made a respectable amount of progress, given the method.&lt;br /&gt;&lt;br /&gt;If I'm lucky, reading Elfen Lied would be closer to the former, as the illustrations give some context. But even if I infrequently need to look things up it wouldn't be too bad. And it would very likely improve my ability to read/write Spanish in general by a noteworthy amount.&lt;br /&gt;&lt;br /&gt;So, I'll probably buy that after money is no longer so tight.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-5369309956949911158?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/5369309956949911158/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=5369309956949911158' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5369309956949911158'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5369309956949911158'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/03/qs-squishy-thing-of-day_22.html' title='Q&apos;s Squishy Thing of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-5898896061484581392</id><published>2010-03-21T11:22:00.001-07:00</published><updated>2010-03-21T11:23:42.270-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='linguistics'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>Q's Squishy Thing of the Day</title><content type='html'>Just saw this today. Perhaps nobody else will find it interesting, but I do.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.wow.com/2010/03/18/wow-rookie-essential-wow-terminology-in-other-languages-thursda/"&gt;Essential WoW terminology in other languages&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-5898896061484581392?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/5898896061484581392/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=5898896061484581392' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5898896061484581392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5898896061484581392'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/03/qs-squishy-thing-of-day.html' title='Q&apos;s Squishy Thing of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-3638932199557552127</id><published>2010-02-25T12:53:00.000-08:00</published><updated>2010-02-25T14:54:54.030-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>Q's Squishy Thing of the Day</title><content type='html'>Meet &lt;a href="http://www.shadyurl.com/index.php"&gt;ShadyURL&lt;/a&gt;. It encodes URLs in things that look like spam, porn, malware, and cults/racism. Some of the things I've linked to various people in the last day:&lt;br /&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Segoe UI;" &gt;&lt;a href="http://5z8.info/PIN-phisher_a1x6x_nakedgrandmas.jpg"&gt;http://5z8.info/PIN-phisher_a1x6x_nakedgrandmas.jpg&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Segoe UI;" &gt;&lt;a href="http://5z8.info/double-your-wang_z2f4t_nazi"&gt;http://5z8.info/double-your-wang_z2f4t_nazi&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Segoe UI;" &gt;&lt;a href="http://5z8.info/worm.exe_i8k3z_stalin-will-rise-again"&gt;http://5z8.info/worm.exe_i8k3z_stalin-will-rise-again&lt;/a&gt;&lt;br /&gt;&lt;a href="http://5z8.info/killallimmigrants_x2l9n_protocols-of-the-elders-of-zion.doc"&gt;http://5z8.info/killallimmigrants_x2l9n_protocols-of-the-elders-of-zion.doc&lt;/a&gt; (best URL so far)&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Segoe UI;" &gt;&lt;a href="http://5z8.info/OPI423098BVMPEMBUDSGND423098889708807909788079_k3j7r_dogporn"&gt;http://5z8.info/OPI423098BVMPEMBUDSGND423098889708807909788079_k3j7r_dogporn&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And, just for fun, here's the Copyright Alliance blog: &lt;/span&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Segoe UI;" &gt;&lt;a href="http://5z8.info/pirate-anything_w2x9e_racist-raps"&gt;http://5z8.info/pirate-anything_w2x9e_racist-raps&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="color: rgb(0, 0, 0);font-family:Segoe UI;" &gt;&lt;br /&gt;And this blog: &lt;a href="http://5z8.info/whitepower_o3q2x_inject_worm"&gt;http://5z8.info/whitepower_o3q2x_inject_worm&lt;/a&gt;, which is awesome, because I'm actually 3/4 German&lt;br /&gt;&lt;br /&gt;And yes, I have been made aware that I'm late to the party on this one.&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-3638932199557552127?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/3638932199557552127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=3638932199557552127' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3638932199557552127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3638932199557552127'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/02/qs-squishy-thing-of-day.html' title='Q&apos;s Squishy Thing of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-4167910388634142421</id><published>2010-02-24T16:33:00.000-08:00</published><updated>2010-02-24T22:34:28.409-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>&amp; Content Filtering</title><content type='html'>Following a brief scuffle with Patrick Ross in the comments of the &lt;a href="http://blog.copyrightalliance.org/"&gt;Copyright Alliance blog&lt;/a&gt;, I thought the topic I briefly discussed deserved elaboration: content filtering. That is, the analysis and identification of illicit content packets as they pass through a router, based on hashing (not so effective) or fingerprinting (more effective), usually followed by dropping the packet.&lt;br /&gt;&lt;br /&gt;I'll discuss the full range of content filtering, though one thing at a time.&lt;br /&gt;&lt;br /&gt;First of all, the specific type I referred to previously: filtering at the internet service provider level. Imagine an ISP that is being legally pressured to do something about file-sharing by copyright industry representatives, a situation hundreds of ISPs around the world find themselves in at this very moment.&lt;br /&gt;&lt;br /&gt;Now, Mr. Sales Rep, from another company that makes deep packet inspection hardware, offers to sell a product to Mr. Business Suit from the ISP, that will solve the file-sharing problem, as many sales reps are currently doing. This company's tests show that the product is 95% effective at identifying and blocking traffic containing illicit copyrighted material, and has a low rate of false-positives. Naturally, Mr. Business Suit at the ISP looks at this product, and sees an amazing solution to all of their problems. Mr. Engineer at the same ISP looks at the product and sees a million-dollar paperweight, and tells Mr. Sales Rep to get out of his office. Nevertheless, convinced by Mr. Sales Rep, Mr. Business Suit purchases the product, and has Mr. Engineer install it.&lt;br /&gt;&lt;br /&gt;Now the product has been installed, and everybody watches eagerly, as Mr. Engineer turns the new product on. Immediately the product begins logging transfers of copyrighted content by the thousands, and successfully blocks them. Yet Mr. Engineer looks at his network statistics and sees that not only is the product having 0 effect on the amount of internet traffic, there is still just as much illicit content being successfully uploaded by users of the ISP.&lt;br /&gt;&lt;br /&gt;What could possibly have gone wrong? And why were the appraisals of the product so drastically different between Mr. Business Suit and Mr. Engineer, to begin with? Is the product defective? Did Mr. Sales Rep lie?&lt;br /&gt;&lt;br /&gt;Well, not exactly.&lt;br /&gt;&lt;br /&gt;What happened is that the ISP's users adapted effortlessly to the new piece of filtering hardware. While it's certainly viable, if implemented competently, to detect and  block things like copyrighted content, this is only possible if you have  access to the data being transmitted. The universal Achilles heel of such identification algorithms is encryption.&lt;br /&gt;&lt;br /&gt;Modern file-sharing software supports end-to-end encryption - the same kind used to secure credit card transactions online: the uploader encrypts the data, the downloader decrypts it, and nothing in the middle can access the data in between the two, because nothing else has the encryption key. This "nothing" includes that million-dollar product our ISP just bought.&lt;br /&gt;&lt;br /&gt;Now, this encryption is not a technology that needs to be developed, nor does it need to be downloaded and installed by the user. It's already there. If a user is able to share files through a P2P application, the encryption code is already in that P2P application; it needs only to be enabled by a user clicking a check box. And, of course, you can be certain that it will be turned on by default in future versions of said software if content filtering by ISPs becomes common.&lt;br /&gt;&lt;br /&gt;In other words, each of those "blocked" uploads the product registers is merely the first of two attempts. A blocked upload is merely an upload that will succeed seconds later,  after the user clicks the box to enable encryption (though if content filtering is widely deployed, users won't even need to do that). Thus, to make a long story short, while you have successfully prevented file-sharers from uploading unencrypted illicit content, you haven't actually prevented a single copyright infringement.&lt;br /&gt;&lt;br /&gt;This is a theoretical problem, not an implementation issue. As such,  there is no basis to hope that this is a limitation that will  ever be overcome in the future.&lt;br /&gt;&lt;br /&gt;But look on the bright side: Mr. Sales Rep got a nice commission off that million bucks the ISP paid his company, and as he technically never lied, the ISP has no legal recourse to argue fraudulent advertising.&lt;br /&gt;&lt;br /&gt;However, the fact that ISP-level filtering is a technological dead-end should not be taken to mean that all filtering technology is useless. As stated, filtering technology can be effective, given that it has access to the data. Of course, the hackers of the world will continually work to find new ways to evade such filtering algorithms, but it should still be possible to successfully filter enough to justify the cost of the filtering hardware/software.&lt;br /&gt;&lt;br /&gt;One example where this works to a satisfactory degree, both in theory and in practice, is YouTube. Because YouTube actually processes and decodes the content uploaded to it, it's impossible for it to not have access to the data - it couldn't function otherwise. As such, it always has access to the full, unencrypted content uploaded, at which point filtering of that content is possible, and in fact is already being performed.&lt;br /&gt;&lt;br /&gt;Dumb file storage sites - sites like RapidShare - which store data without any regard to what type of data it is, fall somewhere in the middle. As they do not require access to the data itself, encryption is entirely possible, and would indeed be capable of evading any filtering of uploaded content done on the part of the site. However, use of this type of encryption would be much more of an inconvenience than is the case with encryption in P2P programs; in this case, encryption must be done manually, by the user, through a completely separate program (almost anything that can make ZIP files can encrypt them, for instance), and the encryption key must be distributed through other channels, such as forums that link to the encrypted file. As such, while filtering at the level of such sites will certainly not prevent such encrypted transmission of content (nor probably even a majority of total transmission), it's possible that filtering systems might reduce sharing of illicit content by some sufficiently valuable fraction by means of sheer annoyance.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-4167910388634142421?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/4167910388634142421/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=4167910388634142421' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4167910388634142421'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4167910388634142421'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/02/content-filtering.html' title='&amp; Content Filtering'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-8479105804281442088</id><published>2010-02-10T22:53:00.000-08:00</published><updated>2010-02-10T23:56:31.363-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><title type='text'>Die! *smash*</title><content type='html'>I have squashed the &lt;a href="http://qstuff.blogspot.com/2010/02/now-what.html"&gt;mystery&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I did some chatting with Merlin (never mind who that is, just that he knows some about the electrical engineering of computers, as well as programming). He gave me a couple of theoretical possibilities what the problem could be, some of which could be tested, others were simply components on the motherboard that I had no way to individually test.&lt;br /&gt;&lt;br /&gt;One thing was the power supply. According to him, it's possible that when data is being sent from the memory to the controller (in 8 blocks of 64 bits), if the power supply is flaky the voltage could droop over time, which could hypothetically explain why the bit only fails only once in each cache line even if the problem is in one of those 64 data lines. However, this was easily disproved, as I do have other power supplies.&lt;br /&gt;&lt;br /&gt;More importantly, while talking to him I thought of my grandma's computer (my computer prior to 2001), which had the same type of memory. While this computer is too old to support 512 meg DIMMs (this was why I couldn't just use it to verify the DIMMs worked and be done with it), it did have some smaller DIMMs in it (256 meg). See where this is going?&lt;br /&gt;&lt;br /&gt;Now I had more than two DIMMs, and with them I was able to demonstrate that the same bit failure occurred with any combination of two DIMMs (although the frequency of the error did vary some depending on the pair used). This proved conclusively that the DIMMs themselves were not responsible, and the problem had to reside in the common element - the motherboard or the CPU. This appears to be a problem that only shows up when both DIMM slots were full.&lt;br /&gt;&lt;br /&gt;Now, it's still possible that it could be a software (BIOS) problem that could be fixed by updating the BIOS, but I don't care to try that, for the reason I mentioned previously.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8479105804281442088?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8479105804281442088/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8479105804281442088' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8479105804281442088'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8479105804281442088'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/02/die-smash.html' title='Die! *smash*'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6932952971993197696</id><published>2010-02-10T16:32:00.000-08:00</published><updated>2010-02-10T16:38:38.570-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>...Now What?</title><content type='html'>A few weeks ago my parents' desktop died. This was my old Athlon XP computer I had before I bought the one I have now (about a year and a half ago). A bit of trivial diagnostics demonstrated that either the CPU or motherboard had died, and I didn't have the parts necessary to determine which. So, my dad went looking on eBay for a replacement motherboard and CPU to go with the existing memory, as they didn't really have the money to buy a new computer right now (actually, I was the one who did most of the looking at the specs, to make sure it would work).&lt;br /&gt;&lt;br /&gt;A few days ago, the motherboard+CPU arrived, and I quickly set to determining whether or not they worked, as the amount of time to return it was limited. As my past experiences have made me a little paranoid in that respect, naturally the first thing I did was run MemTest 86 on it.&lt;br /&gt;&lt;br /&gt;While it seemed to work for the most part, about once every pass (took a couple hours) on test #7, an error would show up. After leaving it running overnight, some patterns emerged. The error was always the 0x02000000 bit getting set when it should be cleared, and it usually occurred when the value written to the memory was 0xFDxxxxxx (less commonly, 0xF9xxxxxx). The base address of the error seemed to always be at 0x3C, 0x7C, 0xBC, or 0xFC. The errors also appeared to cluster in the low 512 megs of the memory space.&lt;br /&gt;&lt;br /&gt;In short, it appeared to be 1 bit every 64 bytes, where the containing byte changes from 11111x01 to 11111x11.&lt;br /&gt;&lt;br /&gt;Separately, neither of the two 512-meg DIMMs shows this problem, regardless of which of the two sockets the DIMM is in (as tested by running MemTest 86 overnight, which would be expected to produce about a dozen errors). However, when put in in one order, this error occurs. Peculiarly, when put in the opposite order, MemTest begins spewing out memory errors before soon crashing (presumably due to memory errors in the locations the program is at).&lt;br /&gt;&lt;br /&gt;So, where is the problem? Well, I wish I knew the answer to that.&lt;br /&gt;&lt;br /&gt;The fact that both DIMMs worked correctly when alone suggests that the DIMMs are good (these are the same ones that were used in the computer that failed, and to my knowledge there was nothing wrong with them then). The fact that each DIMM works in both sockets suggests that it's not a bad socket. The fact that it's every 64 bytes tells me that it's not one of the data lines on the DIMMs or on the  motherboard, as the data width is 64 bits (64 pins). The fact that the error period isn't into  the kilobytes indicates that it's not a CPU cache failure, as I saw &lt;a href="http://qstuff.blogspot.com/2006/05/me.html"&gt;in  the past&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;64 bytes is the size of the cache line for the CPU, which seems to hint that it's somewhere after where the 64-bit memory reads are assembled into whole cache lines; unfortunately, I don't know where exactly this occurs, to narrow down the possibilities. Yet the fact that it only seems to occur in the lowest 512 megs of the memory space is very suspicious, and seems to suggest something with one of the DIMMs, sockets, or data paths on the motherboard, which appear to already be ruled out from earlier tests.&lt;br /&gt;&lt;br /&gt;So, I'm really at a loss as to what to make of this and what to do next, and I've got three days left to do it. I can't test the memory on another computer, because I don't have another computer to test it on. The BIOS could use updating, which could theoretically fix the problem, but I've been reluctant to do that because it's a trivial way to say "You broke it, I'm not giving you a refund!"&lt;br /&gt;&lt;br /&gt;I suppose I need to try mixing and matching the CPUs and motherboards. I need to do that anyway, to find out exactly what broke on the old computer, but it should also tell me whether the problem is in the CPU or motherboard (though nothing more specific than that).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6932952971993197696?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6932952971993197696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6932952971993197696' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6932952971993197696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6932952971993197696'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/02/now-what.html' title='...Now What?'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-7050629798962655313</id><published>2010-02-06T02:10:00.000-08:00</published><updated>2010-02-08T12:12:02.721-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Let's Do Some Math!</title><content type='html'>There are a couple common equations of importance for what I'm working on at the moment. Both of them involve the idea of a set of items, where each item has a probability of being chosen (and more than one may be chosen in some cases). It's trivial to go item by item, draw a random number, and see if that item is chosen, but this is obviously inefficient. I wanted equations that would allow me to stick in a single random number and it will tell me the first relative item to be chosen, with a fixed number of operations.&lt;br /&gt;&lt;br /&gt;The first equation is based on each item in the set having an equal probability of being chosen (note that more than one may be chosen, or none may be chosen):&lt;br /&gt;probability(item) = perItemProbability&lt;br /&gt;&lt;br /&gt;The general form of this decision is (rnd &lt;= perItemProbability), where rnd is between 0 and 1 (as is the case with all instances of rnd in this post). Trivial. The equation we want to derive, however, not quite as much.&lt;br /&gt;&lt;br /&gt;While it's tempting to think that the probability of any of n items being chosen is (perItemProbability * n), it's not. This isn't a linear function. Rather, you have to derive it from the probability that NONE of those items will be chosen, which is exponential.&lt;br /&gt;&lt;br /&gt;(1 - perItemProbability)^n : probability none of n items will be chosen&lt;br /&gt;1 - (1 - perItemProbability)^n : probability that at least one of n items will be chosen&lt;br /&gt;rnd = 1 - (1 - perItemProbability)^n : switch out probability for a random number&lt;br /&gt;1 - rnd = (1 - perItemProbability)^n : arithmetic rearrangement&lt;br /&gt;log(1 - rnd) = log(1 - perItemProbability) * n : take the log of both sides&lt;br /&gt;log(1 - rnd) / log(1 - perItemProbability) = n : arithmetic rearrangement&lt;br /&gt;&lt;br /&gt;This gives us what we want: the index of the first chosen item. Of course you have to watch for values that result in taking log(0). You also have to notice that the range of the result is [0, infinity]; this is correct, but if the value is greater than the upper bound of your set of items, you have to recognize that no item was chosen.&lt;br /&gt;&lt;br /&gt;Next up is the case where the probability of each item follows a geometric series:&lt;br /&gt;probability(n + 1) = probability(n) * (1/divisor)&lt;br /&gt;probability(0) = p0&lt;br /&gt;sum of probabilities = 1&lt;br /&gt;&lt;br /&gt;With this series there's no misleading simple solution, so we're forced to go straight to a more complex one. We know the sum of all the probabilities is 1, but we don't know what value of p0 to use to produce that sum. We can trivially calculate this using the geometric series equation:&lt;br /&gt;1 = p0 * (1 - (1/divisor)^n) / (1 - (1/divisor)) : geometric series equation&lt;br /&gt;p0 = (1 - (1/divisor)) / (1 - (1/divisor)^n) : arithmetic rearrangement&lt;br /&gt;&lt;br /&gt;Okay, that's the easy part. Now the equation itself. Here again we'll solve for n:&lt;br /&gt;rnd = p0 * (1 - (1/divisor)^n) / (1 - (1/divisor)) : substitute rnd for sum of probability&lt;br /&gt;rnd / p0 * (1 - (1/divisor)) = 1 - (1/divisor)^n : arithmetic rearrangement&lt;br /&gt;1 - (rnd / p0) * (1 - (1/divisor)) = (1/divisor)^n : arithmetic rearrangement&lt;br /&gt;log(1 - (rnd / p0) * (1 - (1/divisor))) = log(1/divisor) * n : log of both sides&lt;br /&gt;n = log(1 - (rnd / p0) * (1 - (1/divisor))) / log(1/divisor) : arithmetic rearrangement&lt;br /&gt;&lt;br /&gt;And thus the solution: a long, ugly equation to calculate something simple. Again, you have to watch for values that result in errors: divisor must be greater than 1; but that's pretty obvious: a geometric series will only sum to a finite number if (1/divisor) is less than 1. You also have to note that when rnd = 1, n = the number of items in the set, which will be out of bounds.&lt;br /&gt;&lt;br /&gt;Isn't math fun?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-7050629798962655313?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/7050629798962655313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=7050629798962655313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7050629798962655313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7050629798962655313'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/02/lets-do-some-math.html' title='Let&apos;s Do Some Math!'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-5542123974063464775</id><published>2010-02-04T18:10:00.000-08:00</published><updated>2010-02-10T17:01:44.820-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>&amp; Solid State Stuff</title><content type='html'>Pretty soon I'm going to be looking to upgrade some things on my computer, starting with the hard drive. In addition to getting a large disk to begin using for archived anime (as opposed to the large stack of DVDs I've burned), I was going to get a &lt;a href="http://en.wikipedia.org/wiki/Solid_state_drive"&gt;solid-state disk&lt;/a&gt; to put my Windows 7 that I won in a raffle a couple weeks ago on.&lt;br /&gt;&lt;br /&gt;For anyone not familiar with them, SSDs have the benefit that they have 0 seek time (as opposed to about 9 ms for HDs), combined with linear read speeds several times that of HDs. For very large and contiguous files, which involve only linear access, an SSD could be 3 or 4x as fast as an HD. But for accessing large numbers of small, non-contiguous files, which involve many seeks, the difference is much, much larger. Thus SSDs can be anywhere from substantially faster to massively faster than HDs, depending on the type of access.&lt;br /&gt;&lt;br /&gt;But what exactly do I do with the SSD when I get it? Prior to Wednesday, the answer was obvious: use it as my boot drive. That is, put Windows and frequently used programs on it, and use a separate HD to put large and infrequently used stuff on.&lt;br /&gt;&lt;br /&gt;Today, however, there's another option, thanks to the announcement of &lt;a href="http://www.bit-tech.net/news/hardware/2010/02/03/silverstone-announces-hybrid-ssd-hard-disk/1"&gt;this evil little thing&lt;/a&gt;: a disk controller which combines an HD and an SSD, using the SSD as a massive cache for the much larger HD. That is, instead of having the SSD serve as a dedicated boot drive, it's used to cache frequently used files from all over the HD (when talking about an 80 gig cache, "frequently" probably amounts to  once every week or two).&lt;br /&gt;&lt;br /&gt;One obvious advantage is that the superior performance of the SSD is applied not just to system files (e.g. Windows), but also to anything on the disk that gets used frequently. Similarly, you don't need to let part of the SSD go to waste if you don't have enough files to fill it up (I'm told using an SSD as your boot drive takes 30-40 gigs of SSD, while higher end SSDs go up to 256 gigs). Another big benefit is that you don't have to manually split files that are normally on the boot drive (e.g. Program Files and the Users documents folder) between the SSD and HD depending on whether you want them fast or slow; for example, I wouldn't want to put downloaded anime on my (dedicated) SSD, nor would I want my SSD bloated with the various bulky compiler intermediates.&lt;br /&gt;&lt;br /&gt;Now, the big question is how exactly this is going to work. According to the manufacturer, it requires a driver for Windows in order to work. This suggests that caching may all be done in software, rather than hardware. This brings up the obvious question: in what cases the cache will be used? If the cache is only used within the current Windows boot (essentially serving as a gigantic system cache), this won't be very useful, at least for me (perhaps for a database server, with multiple terabytes of database, a 100+ gig cache would be substantially beneficial). I already have 8 gigs of RAM, about 4 of which (at a minimum) is available to be used by the system cache, which is a pretty decent cache for one session (and RAM is much faster than an SSD, anyway).&lt;br /&gt;&lt;br /&gt;From the write-up, however, it sounds like the cache at least persists between Windows boots, which would mean it wouldn't quite be that bad. However, if the caching is all software-based via a Windows driver, this obviously means that it won't be of any benefit prior to loading that driver - that is, during boot up/shut down and going into/out of hibernate, which are things I was hoping to gain out of getting an SSD.&lt;br /&gt;&lt;br /&gt;I guess we'll find out when the thing ships, in 3 weeks or so.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-5542123974063464775?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/5542123974063464775/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=5542123974063464775' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5542123974063464775'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5542123974063464775'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/02/sold-state-stuff.html' title='&amp; Solid State Stuff'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-5342054960702427127</id><published>2010-01-31T16:07:00.001-08:00</published><updated>2010-02-02T14:19:42.732-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>Random Fact of the Day</title><content type='html'>You can't install SilverLight on a Pentium 2. It has to be something that supports &lt;a href="http://en.wikipedia.org/wiki/Streaming_SIMD_Extensions"&gt;SSE&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-5342054960702427127?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/5342054960702427127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=5342054960702427127' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5342054960702427127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5342054960702427127'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/01/ran.html' title='Random Fact of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-2530802196932734398</id><published>2010-01-23T20:00:00.000-08:00</published><updated>2010-01-23T20:43:42.243-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>EPIC FAIL</title><content type='html'>I got a letter from Wells Fargo bank with a new credit card, today. Nothing out of the ordinary in that respect, but the extent Wells Fargo failed in the process is pretty remarkable.&lt;br /&gt;&lt;br /&gt;The first page was all the stuff you'd expect - credit card glued on, as well as account number and other info, and instructions to use it. The second page is shown below (the back is completely blank):&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_9GysFr4NPa4/S1vLby4j-lI/AAAAAAAAAMY/H02LhvUXPxo/s1600-h/WellsFargoFail1.gif"&gt;&lt;img style="cursor: pointer; width: 291px; height: 400px;" src="http://4.bp.blogspot.com/_9GysFr4NPa4/S1vLby4j-lI/AAAAAAAAAMY/H02LhvUXPxo/s400/WellsFargoFail1.gif" alt="" id="BLOGGER_PHOTO_ID_5430157454101183058" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Looks completely innocuous and generic, right? Except for that black block in the lower right that I filled in. There is a bar-code and, in 6 point font, a number of numbers (most that I don't recognize), including the credit card number itself. If you weren't looking for it, you would most certainly never have seen it.&lt;br /&gt;&lt;br /&gt;The number of people who have thrown that page away without ever realizing it had their credit card number on it is surely uncountable. Funny how a page about guarding against fraud sets you up perfectly for fraud by printing entirely unnecessary sensitive information on a completely generic page (that would have been cheaper to print without that information). You have to wonder if there's some malicious intent, there.&lt;br /&gt;&lt;br /&gt;So, after the facepalm, I go online to activate the new card. After logging in and going to the activation page on Wells Fargo's (secure) web site, I'm met by this page:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_9GysFr4NPa4/S1vLkcr1UlI/AAAAAAAAAMg/fDfc2t6yQwc/s1600-h/WellsFargoFail2.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 307px;" src="http://4.bp.blogspot.com/_9GysFr4NPa4/S1vLkcr1UlI/AAAAAAAAAMg/fDfc2t6yQwc/s400/WellsFargoFail2.gif" alt="" id="BLOGGER_PHOTO_ID_5430157602761036370" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Birth date? Work phone number? Really? It's been known for a long time that "security questions" &lt;a href="http://kernelmustard.com/2007/01/09/security-is-hard-part-8-insecurity-questions/"&gt;are major security vulnerabilities&lt;/a&gt;, but this may just set a new record as to extent.&lt;br /&gt;&lt;br /&gt;I can't say I can trust Wells Fargo after that rather brilliant display of insecurity.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-2530802196932734398?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/2530802196932734398/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=2530802196932734398' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2530802196932734398'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2530802196932734398'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/01/epic-fail.html' title='EPIC FAIL'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_9GysFr4NPa4/S1vLby4j-lI/AAAAAAAAAMY/H02LhvUXPxo/s72-c/WellsFargoFail1.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-7304464862017287383</id><published>2010-01-19T17:45:00.001-08:00</published><updated>2010-01-19T17:47:17.068-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>What the Goat</title><content type='html'>&lt;blockquote&gt;The National Weather Service has issued a tornado warning for the South Los Angeles, Long Beach and Whittier [right about here] areas as a powerful new storm moves ashore.&lt;/blockquote&gt;&lt;a href="http://latimesblogs.latimes.com/lanow/2010/01/tornado-warning-issued-for-south-los-angeles-long-beach-and-whittier.html"&gt;Tornado Warning Issued for South Los Angeles, Long Beach, and Whittier&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;A tornado watch. In Los Angeles county. Has that &lt;span style="font-style: italic; font-weight: bold;"&gt;ever&lt;/span&gt; happened before?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-7304464862017287383?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/7304464862017287383/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=7304464862017287383' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7304464862017287383'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7304464862017287383'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/01/what-goat.html' title='What the Goat'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-5465744869100600602</id><published>2010-01-18T22:57:00.000-08:00</published><updated>2010-01-18T23:08:57.907-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><title type='text'>Random Fact of the Day</title><content type='html'>Watching CSI: Miami I learned something new: that receiving a liver transplant* can change your blood type to that of the donor. I'd never heard anything about that before, so I had to do a Google search before believing it. Apparently it's actually happened; &lt;a href="http://www.digitaljournal.com/article/249300"&gt;once&lt;/a&gt;. It seems that stem cells in the liver managed to detach and land in the bone marrow of the recipient, and take over the marrow.&lt;br /&gt;&lt;br /&gt;This makes me wonder. If I understand the biology involved correctly, this would only be possible if the blood type changed in a particular direction. In any other direction you'd get the same effect you'd get from getting an incompatible blood transfusion. Thus my question: might this have happened before, but been misclassified as simple organ rejection?&lt;br /&gt;&lt;br /&gt;*In theory this is probably possible with most transplants, given that it involves stem cells being transported with the organ.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-5465744869100600602?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/5465744869100600602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=5465744869100600602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5465744869100600602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5465744869100600602'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/01/random-fact-of-day_18.html' title='Random Fact of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-2153969408341334699</id><published>2010-01-12T12:00:00.000-08:00</published><updated>2010-01-15T15:03:09.207-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Computer Book Library</title><content type='html'>This post lists some of the computer books I have on my shelf, between text books and books I bought outside of school. This list is meant to provide readers with books they might be interested in reading, and so is limited to the books most likely to be of interest to others. While I list the versions that I have, myself, the links to the books on Amazon are to the most recent edition at the time of writing about them.&lt;br /&gt;&lt;br /&gt;This post is likely to be updated from time to time in the future.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Game-Engine-Design-Second-Interactive/dp/0122290631/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1263169926&amp;amp;sr=8-1"&gt;3D Game Engine Design&lt;/a&gt;, 2nd ed&lt;br /&gt;David Eberly, Morgan Kaufman, 2006&lt;br /&gt;Covers development of a 3D game engine that includes graphics, physics, and a few lesser topics (though the focus on the book is definitely graphics). Covers both the theory behind concepts and actual implementation of a complete working engine; this latter point makes it vastly superior to more typical graphics books, which usually cover the theory but not a complete implementation.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Artificial-Intelligence-Structures-Strategies-Complex/dp/0321545893/ref=ntt_at_ep_dpt_1"&gt;Artificial Intelligence&lt;/a&gt;, 5th ed&lt;br /&gt;George Lugar, Pearson Education, 2004&lt;br /&gt;Computer science textbook I used in the senior-level course.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Programming-Program-Design-Including-Structures/dp/142390222X/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1263170256&amp;amp;sr=1-1"&gt;C++ Programming: Program Design Including Data Structures&lt;/a&gt;,&lt;br /&gt;D.S. Malik, Couse Technology, 2002&lt;br /&gt;First year (for me) college textbook&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=ntt_at_ep_dpi_1"&gt;Code Complete&lt;/a&gt;&lt;br /&gt;Steve McConnell, Microsoft Press, 1993&lt;br /&gt;Handbook of coding best practices for minimizing bugs and improving maintainability.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Developing-Windows-Device-Drivers-Programmers/dp/0768682258/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1263170543&amp;amp;sr=1-1"&gt;Developing Windows NT Device Drivers&lt;/a&gt;&lt;br /&gt;Edward Dekker and Joseph Newcomer, Addison Wesley, 1999&lt;br /&gt;A rather dated guide to programming Windows NT (4.0) device drivers.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Mmurtl-V1-0-Richard-Burgess/dp/1588530000/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1263170665&amp;amp;sr=1-1"&gt;Developing Your Own 32-Bit Operating System&lt;/a&gt;&lt;br /&gt;Richard Burgess, SAMS Publishing, 1995&lt;br /&gt;Prior to the Linux phenomenon, this was pretty much the only book that showed you how to create a full, real, working operating system for a modern computer (at the time, anyway). Throughout the book the author codes the example MMURTL (Message-based MUltitasking Real-Time kerneL), a (some redundancy, here) 32-bit message-passing, &lt;a href="http://en.wikipedia.org/wiki/Preemptive_multitasking#Preemptive_multitasking"&gt;preemptive-multitasking&lt;/a&gt; operating system that runs on x86 computers, in 32-bit assembly + C, and several sample programs (including the command-line interpreter and debugger) in C.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Fundamentals-Computer-Graphics-Peter-Shirley/dp/1568814690/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1263170737&amp;amp;sr=1-1"&gt;Fundamentals of Computer Graphics&lt;/a&gt;, 2nd ed&lt;br /&gt;Peter Shirley et al., A K Peters, 2005&lt;br /&gt;A fourth-year (for me) college textbook. Like most books of its kind, it teaches you the theory behind graphics (and, if you're lucky, gives you pseudocode for some concepts), but leaves you on your own to figure out how to create a working graphics engine (if you have the need to do so).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Fundamentals-Database-Systems-Ramez-Elmasri/dp/0321369572/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1263171672&amp;amp;sr=1-1"&gt;Fundamentals of Database Systems&lt;/a&gt;, 5th ed&lt;br /&gt;Ramez Elmasri and Shamkant Navathe, Pearson Education, 2007&lt;br /&gt;A fourth-year (for me) college text book on databases. Covers from the basics to the advanced, as well as SQL programming, both in theory and practice.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Game-Architecture-Design-Andrew-Rollings/dp/0735713634/ref=sr_1_3?ie=UTF8&amp;amp;s=books&amp;amp;qid=1263171866&amp;amp;sr=1-3"&gt;&lt;br /&gt;Game Architecture and Design&lt;/a&gt;&lt;br /&gt;Andrew Rollings and Dave Morris, Coriolis Group, 1999&lt;br /&gt;A guide to the complete development process for a commercial game. The first section covers developing a game idea and balancing gameplay, the second section covers project and team management, and the third section covers development from architectural design (the thing code is based on) to production and postmortem analysis. The vast majority of the book is at a higher level, summarizing the entire game development process and the lessons learned by the author from his experience in commercial game development, though the author does create a (simple) working game in the process (several other game ideas are discussed in various chapters, but not developed into the full games).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Game-Coding-Complete-Third-McShaffry/dp/1584506806/ref=sr_1_1?ie=UTF8&amp;amp;s=books&amp;amp;qid=1263172530&amp;amp;sr=1-1"&gt;Game Coding Complete&lt;/a&gt;, 3rd ed&lt;br /&gt;Mike McShaffry et a., Charles River Media, 2009&lt;br /&gt;A guide to the game development process and development of game systems. While the scope of material in this book is much the same as other game programming books (e.g. Tricks of the Windows Game Programming Gurus), this book distinguishes itself on quality and scalability. All game programming books invariably contain a guide to the various APIs your game will need to use (e.g. DirectX) and a survey of game technology (e.g. 3D graphics, AI, and networking). However, most books teach you from the perspective of a hobbyist getting into game programming, teaching you easy things that work okay for small games, but lack the power and scalability to deal with a large commercial game (and omit things that aren't necessary for small games).&lt;br /&gt;&lt;br /&gt;This book dedicates itself to filling in those gaps, addressing frequently-omitted topics such as the build process, memory management and resource caching, event management, scripting support (the engine the author creates throughout the book is actually a data-driven engine based on Lua scripting), debugging, parallel programming, etc. Of course, it also contains the mandatory survey of game-related technologies, but I haven't looked at those parts and don't expect too much, as most of them are best left to their own books (graphics, physics, networks, AI, etc.), given the overwhelming broadness of those fields.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Windows-via-Pro-Jeffrey-Richter/dp/0735624240/ref=ntt_at_ep_dpi_1"&gt;Programming Applications for Windows&lt;/a&gt;, 4th ed&lt;br /&gt;Jeffrey Richter, Microsoft Press, 1999&lt;br /&gt;Perhaps better described by its older name, Advanced Windows, this is the gold standard in "advanced" Windows API programming - things such as multithreading, advanced memory management, DLLs (including DLL injection and function hooking), exception-handling, and advanced window messaging.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Programming-Microsoft-Windows-Forms-Developer/dp/0735621535/ref=ntt_at_ep_dpt_7"&gt;Programming Windows&lt;/a&gt;, 5th ed&lt;br /&gt;Charles Petzold, Microsoft Press, 1998&lt;br /&gt;&lt;span style="font-style: italic;"&gt;The&lt;/span&gt; first book to read on Windows API programming. Covers a broad range of topics from basic windows and controls to more advanced topics such as (basic) graphics, printing, multithreading, network communication, etc.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Programming-Windows-Second-Jeff-Prosise/dp/1572316950/ref=ntt_at_ep_dpt_1"&gt;Programming Windows with MFC&lt;/a&gt;, 2nd ed&lt;br /&gt;Jeff Prosise, Microsoft Press, 1999&lt;br /&gt;The definitive guide to the &lt;a href="http://en.wikipedia.org/wiki/Microsoft_Foundation_Class_Library"&gt;Microsoft Foundation Class library&lt;/a&gt;, a C++ framework that wraps the Windows API. Analogous to Programming Windows, this was the book to read if you needed to learn MFC, though as MFC is easier to program than the Windows API, this book covers topics beyond those in Programming Windows. MFC is essentially obsolete now that .NET has become so common, though I'm told some people still have to deal with it in older software at their jobs.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Tricks-Windows-Game-Programming-Gurus/dp/0672323699/ref=ntt_at_ep_dpt_2"&gt;Tricks of the Windows Game Programming Gurus&lt;/a&gt;&lt;br /&gt;André LaMothe, SAMS Publishing, 1999&lt;br /&gt;The Game Programming Gurus has been pretty well respected throughout its life. This was the 2D Windows game incarnation of the series (also see the companion &lt;a href="http://www.amazon.com/Tricks-Programming-Gurus-Advanced-Graphics-Rasterization/dp/0672318350/ref=ntt_at_ep_dpi_3"&gt;Tricks of the 3D Game Programming Gurus&lt;/a&gt;); it covered basic Windows programming, the various DirectX systems, and then a survey of the various fields in game programming (like those mentioned a ways back). As stated above, this (and presumably the 3D version, which I haven't seen) is more of an introduction to game programming than a reference that would be useful at a real game programming job.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Visual-2008-How-Program-3rd/dp/013605322X/ref=sr_1_3?ie=UTF8&amp;amp;s=books&amp;amp;qid=1263176207&amp;amp;sr=1-3"&gt;Visual C# 2005 How to Program&lt;/a&gt;, 2nd ed&lt;br /&gt;Paul Deitel, Pearson Education, 2005&lt;br /&gt;Lower-division college textbook on C# programming (at my school C and C++ were first-year courses, C#/Java/etc. were second-year).&lt;br /&gt;&lt;br /&gt;Lastly, a couple books on the list of things to buy:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Game-Engine-Architecture-Jason-Gregory/dp/1568814135/"&gt;Game Engine Architecture&lt;/a&gt;&lt;br /&gt;Jason Gregory, A K Peters, 2009&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.amazon.com/Real-Time-Rendering-Third-Tomas-Akenine-Moller/dp/1568814240/"&gt;Real-Time Rendering&lt;/a&gt;, 3rd ed&lt;br /&gt;Tomas Akenine-Moller, Eric Haines, and Naty Hoffman, A K Peters, 2008&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-2153969408341334699?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/2153969408341334699/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=2153969408341334699' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2153969408341334699'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2153969408341334699'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/01/computer-book-library.html' title='Computer Book Library'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-307827691849865288</id><published>2010-01-10T16:00:00.000-08:00</published><updated>2010-08-17T23:54:49.537-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>Bibliography - Programming</title><content type='html'>&lt;span&gt;This post is a partial directory of the various programming and reverse-engineering I've done over the last 12 years, especially those that produced some manner of result (program, specification, or processed data). This list may omit projects that are too old, too obscure, too uninteresting, or that I just don't remember off the top of my head; it also omits most projects that were done as assignments or term projects in school. With a handful of exceptions, all of these are entirely my own work. With the exception of the few most significant projects being moved to the top, the list is in alphabetical order.&lt;br /&gt;&lt;br /&gt;This list may undergo updates in the future.&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;(CHK) &lt;span style="font-weight: bold;"&gt;Starcraft Map File Format&lt;/span&gt; [reverse-engineering]&lt;br /&gt;Reverse-engineering of most of the Starcraft map file format. This was my first modding community project, and it was for this that I was invited to join &lt;a href="http://www.campaigncreations.org/"&gt;Campaign Creations&lt;/a&gt; in 1998. This consisted of repeated edits of a map in the Starcraft map editor (StarEdit) and then observing the changes in the map file it generates. Perhaps one of the most impressive parts of this accomplishment was that the vast majority of this was done using nothing more than the DOS edit.com utility and Windows calculator; no true hex editor, no disassembler or debugger (at that time I wasn't even familiar with reverse-engineering), etc.&lt;br /&gt;&lt;br /&gt;It looks like this spec has become difficult to come by these days. &lt;a href="http://www.campaigncreations.org/"&gt;Campaign Creations&lt;/a&gt; appears to no longer have it (I'll have to get that fixed) and only a few modified and/or butchered copies of it found on Google, some lacking credits for who wrote it. So, &lt;a href="http://quantam.devklog.net/CHKFormat.htm"&gt;here's&lt;/a&gt; the version I still have on my computer.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MoPaQ 2000&lt;/span&gt; [programming]&lt;br /&gt;This (a.k.a. MPQ2K) was the project that really put the name Quantam on the Blizzard game modding map: the first stable, full-featured MPQ editor. Prior to this there was already a full-featured MPQ editor (I think the name was MPQEdit), however the extreme instability and bugginess meant that it was widely considered worse than nothing, and rarely used.&lt;br /&gt;&lt;br /&gt;MPQ2K was a command-line user interface for the Lelik MPQ API, a library that hijacked the Starcraft Campaign Editor (StarEdit) and called the MPQ-writing functions it contained (as Starcraft maps are packaged into MPQ archives), without ever knowing the details of the MPQ format, itself (it's worth noting that this is where I learned about breaking and entering into processes and hooking functions). At the same time as the library, Lelik released a sample editor (I believe the name was MPQ Archiver) that the MPQ2K interface design used as a starting point; it was very clumsy and minimalistic, however, and lacked the major features that would make MPQ2K popular, such as scripting. MPQ2K remained &lt;span style="font-style: italic;"&gt;the&lt;/span&gt; MPQ editor for several years, until cumulative speed improvements finally allowed &lt;a href="http://shadowflare.samods.org/dwnload.html#WinMPQ"&gt;WinMPQ&lt;/a&gt;, a graphical MPQ editor, to seize the title of most popular MPQ editor.&lt;br /&gt;&lt;br /&gt;Understanding the significance of a practical MPQ editor requires some knowledge of the context. Prior to the use of MPQs, the only option to modify Starcraft game data, apart from what could be done in the map editor alone, was StarDraft, the predecessor to MPQDraft. StarDraft allowed in-memory patching of most Starcraft data files, allowing much more than was possible with the map editor alone (e.g. modification of sound effects, graphics, gameplay data such as unit statistics, etc.). While this was a hugely important development that essentially founded the Starcraft modding community (apart from custom maps), StarDraft suffered from several severe shortcomings that drastically limited its practicality: it was version-specific (meaning that every time a Starcraft patch was released StarDraft had to be manually updated by the coder before it could work with the new version), it could not replace music and certain other files, and, perhaps most significantly, it tended to actually slow down the game, degrading gameplay noticeably.&lt;br /&gt;&lt;br /&gt;Thus, StarDraft was the first revolution in Starcraft modding, and use of MPQ files was the second. The replacement of StarDraft with custom MPQs as the basis for community mods solved many of these problems that plagued StarDraft. Music files could now be patched (although a handful of relatively minor files remained unpatchable until the coming of MPQDraft); as well, as MPQs were used natively by Starcraft and other Blizzard games, rather than requiring hacking into the game via StarDraft, this approach meant no gameplay degradation; it also meant this method could be applied to other Blizzard games that used MPQs, not merely Starcraft. This made StarDraft obsolete overnight.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MoPaQ File Format&lt;/span&gt; [reverse-engineering]&lt;br /&gt;The complete reverse-engineering of the MPQ archive format and publishing of what remains the authoritative modder's specification the format. Most of this was performed during development of MoPaQ 2000 2.0. While Lelik reverse-engineered StarEdit sufficiently to allow LMPQAPI to call functions in the Blizzard MPQ API in StarEdit, he never actually looked at the MPQ format itself. Thus the work fell to me to provide functions that didn't exist in StarEdit, by writing code that edited the MPQs directly (code which was then integrated into LMPQAPI 2.0). This was also where I first learned how to reverse-engineer a program via disassembly and debugging. While I gave out a lot of information about the format to a number of people on forums and other media, I didn't actually release a full spec document until some time later (the official version of the spec is &lt;a href="http://wiki.devklog.net/index.php?title=The_MoPaQ_Archive_Format"&gt;here&lt;/a&gt;, though as it's a wiki it's been known to be vandalized from time to time).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;MPQDraft&lt;/span&gt; [reverse-engineering, programming]&lt;br /&gt;The third revolution in Blizzard game modding, MPQDraft perfected the MPQ file technique. Like StarDraft, MPQDraft consisted of a loader that actively invaded the game being patched by a mod; however, MPQDraft suffered from none of the problems of StarDraft: it was version (and game) independent, it finally solved the problem of unpatchable files once and of all, and did not produce any gameplay degradation.&lt;br /&gt;&lt;br /&gt;Like StarDraft, MPQDraft allowed the creation of "self-executing MPQs", which allow authors of mods to conveniently distribute large, complex mods in single executable files. However, MPQDraft added support for a plugin system, which allowed developers to add on new functionality to mods, while still making use of the basic functionality of MPQDraft. A couple examples of the most noteworthy plugins developed for MPQDraft are MemGraft (now obsolete), which allowed modification of data stored in the Starcraft executable itself (as opposed to in the Starcraft data files), and ThunderGraft (described below).&lt;br /&gt;&lt;br /&gt;MPQDraft is now open-source, &lt;a href="http://sourceforge.net/projects/mpqdraft/"&gt;on SourceForge&lt;/a&gt;. Surprisingly, it still gets more than 600 downloads each month (this is only counting downloads through the SourceForge page; mirrors such as the one on Campaign Creations would not be counted), despite the fact that the most recent game it works on, Warcraft III, is about 8 years old, now.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ThunderGraft&lt;/span&gt; [reverse-engineering, programming]&lt;br /&gt;The third of my major modding programs, ThunderGraft adding the ability to play modern audio compression formats (e.g. MP3 and Ogg Vorbis) to older Blizzard games, especially Starcraft. Prior to Warcraft III, Blizzard games used either raw &lt;a href="http://en.wikipedia.org/wiki/Pulse-code_modulation"&gt;PCM&lt;/a&gt; (Diablo) or compressed ADPCM (Starcraft, Diablo II, and Warcraft II) audio formats to store music and sound effects; both formats were undesirable for mods because they were either very bulky (in the case of PCM) or resulted in noticeable loss of audio quality with sub-optimal file sizes (ADPCM). ThunderGraft replaced the entire music streaming system of the games with its own, using the &lt;a href="http://www.fmod.org/index.php/products/fmodex"&gt;FMod Ex&lt;/a&gt; audio library to perform audio decoding of any of the multitude of compression formats the library supports. To my knowledge, it is, six years later, still the only modding tool to attempt such a feat. I finally got around to cleaning up and releasing &lt;a href="http://sourceforge.net/projects/thundergraft/"&gt;ThunderGraft&lt;/a&gt; as open source a couple months ago on SourceForge, though given that the most recent game it supports, Diablo II, is about 10 years old, and the fact that broadband has made small mod sizes less critical than it was 10 years ago, it sees little use today (only about 30 downloads through SourceForge per month).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Allocation Benchmark&lt;/span&gt; [reverse-engineering, programming]&lt;br /&gt;A project to examine the relative performance of several memory allocators - the Windows heap, Windows &lt;a href="http://msdn.microsoft.com/en-us/library/aa366750%28VS.85%29.aspx"&gt;low-fragmentation heap&lt;/a&gt;, &lt;a href="http://www.hoard.org/"&gt;Hoard&lt;/a&gt; allocator, and the Blizzard Storm allocator (SMem, a custom &lt;a href="http://en.wikipedia.org/wiki/Buddy_memory_allocation"&gt;buddy allocator&lt;/a&gt;). Allocation, free, and resize operations were logged from an actual game of Warcraft III via function hooking, then fed in order to each allocator while the duration of each operation is measured, and the results compared. Covered some in &lt;a href="http://www.google.com/custom?domains=qstuff.blogspot.com&amp;amp;q=Hoard&amp;amp;sa=Search&amp;amp;sitesearch=qstuff.blogspot.com&amp;amp;client=pub-7330245220228346&amp;amp;forid=1&amp;amp;ie=ISO-8859-1&amp;amp;oe=ISO-8859-1&amp;amp;cof=GALT%3A%23008000%3BGL%3A1%3BDIV%3A%23336699%3BVLC%3A663399%3BAH%3Acenter%3BBGC%3AFFFFFF%3BLBGC%3A336699%3BALC%3A0000FF%3BLC%3A0000FF%3BT%3A000000%3BGFNT%3A0000FF%3BGIMP%3A0000FF%3BFORID%3A1&amp;amp;hl=en"&gt;various posts&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;AUS Decode&lt;/span&gt; [reverse-engineering, programming]&lt;br /&gt;This project consisted of reverse-engineering the archive (AIF) and digital audio (AUS) file formats in the &lt;a href="http://en.wikipedia.org/wiki/Mega_Man_Anniversary_Collection"&gt;Mega Man Anniversary Collection&lt;/a&gt; to create a decoder that could extract the music directly from the game. Both AIF and AUS file formats were previously unexamined and undocumented, although the audio compression algorithm turned out to be the documented Sony &lt;a href="http://en.wikipedia.org/wiki/Adaptive_DPCM"&gt;ADPCM&lt;/a&gt; variant VAG. Reverse-engineering of both formats was accomplished with nothing more than a hex editor (no disassembler or debugger). I talked a &lt;a href="http://www.google.com/custom?domains=qstuff.blogspot.com&amp;amp;q=%22real+life+adventures%3A+Mega+Man%22&amp;amp;sa=Search&amp;amp;sitesearch=qstuff.blogspot.com&amp;amp;client=pub-7330245220228346&amp;amp;forid=1&amp;amp;ie=ISO-8859-1&amp;amp;oe=ISO-8859-1&amp;amp;cof=GALT%3A%23008000%3BGL%3A1%3BDIV%3A%23336699%3BVLC%3A663399%3BAH%3Acenter%3BBGC%3AFFFFFF%3BLBGC%3A336699%3BALC%3A0000FF%3BLC%3A0000FF%3BT%3A000000%3BGFNT%3A0000FF%3BGIMP%3A0000FF%3BFORID%3A1&amp;amp;hl=en"&gt;tiny bit&lt;/a&gt; about this, but never said much about the technical side of it or released the code.&lt;br /&gt;&lt;br /&gt;(BIN) &lt;span style="font-weight: bold;"&gt;Diablo II Binary Data Format&lt;/span&gt; [reverse-engineering]&lt;br /&gt;Reverse-engineering of a number of major Diablo II binary data formats, e.g. armor.bin, itemtypes.bin monstats.bin, treasureclassex.bin, etc. These files are compiled binary versions of the SLYK spreadsheet files containing game global data. This was originally done with the intent of making a data editor tentatively called HellForge, but I never got around to that. I don't believe I ever released the specs of the BIN files; if I did, it would have been on &lt;a href="http://phrozenkeep.hugelaser.com/"&gt;Phrozen Keep&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;DxWnd&lt;/span&gt; [reverse-engineering, programming]&lt;br /&gt;&lt;a href="http://forum.valhallalegends.com/index.php?topic=5213.0"&gt;DxWnd&lt;/a&gt; allows full-screen DirectDraw games that do not support windowed-mode DirectDraw to run in a window. I can't remember whether the initial idea was mine or Skywing's, but I did the initial research and reverse-engineering for the program and came up with the basic method. Skywing then wrote the code and debugged the cases that required modifications to my basic method (e.g. programs that combine Windows GDI and DirectDraw for graphics, such as the Diablo/Starcraft/Warcraft 2 Battle.net interface). I later added code to support window resizing via Direct3D, rather than the standard drawing method using GDI, though I can't remember if that code ever got released.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;E Terra&lt;/span&gt; [programming]&lt;br /&gt;A real-time strategy game based on ecology and evolution. Because this game focuses on nature and the organic, rather than humanity and society, the gameplay is substantially different than any existing RTS I've heard of, though it's bears some resemblance to &lt;a href="http://en.wikipedia.org/wiki/Populous_%28series%29"&gt;Populous&lt;/a&gt;. E.g. there are no unit classes - unit "classes" are created by the player through gameplay/evolution; units are not built/trained - they are born automatically; etc. Current status: awaiting the motivation to work on it more.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Engram&lt;/span&gt; [design]&lt;br /&gt;The name a &lt;a href="http://en.wikipedia.org/wiki/Portmanteau"&gt;Portmanteau&lt;/a&gt; contraction of "English program", a programming language based on a subset of natural English. This was something I started working on early in my compilers class, when I heard we were each going to be writing a compiler as a term project. Work on it came to an abrupt end when I learned that we didn't get to choose the language for our compilers. Other than what I communicated to a friend in IRC and IM, I never really wrote down a specification or anything.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;LibQ&lt;/span&gt; [programming]&lt;br /&gt;A small, minimalistic cross-platform library (designed for at least Windows and POSIX support) of highly platform-dependent features, such as multithreading (more specifically, synchronization, inter-thread/process communication, and atomic operations and structures), endian-conversion, and high-performance file I/O. Talked about extensively on this blog, though that was before I started using tags or anything to make the posts easy to find.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;NWNScript Compiler&lt;/span&gt; [programming]&lt;br /&gt;A compiler capable of compiling NWScript, the world scripting language used in NeverWinter Nights, NWN2, and  Dragon Age, to native machine code for use in Skywing's NWN2 standalone server. This is the first attempt at such a thing that I'm familiar with; both the original games and Skywing's standalone server previously implement interpreters to execute the scripts.&lt;br /&gt;&lt;br /&gt;In addition to the analyzer, which parses the NWScript bytecode files and generates intermediate representation code, two backend code generators were created to produce native code by proxy. Skywing's backend generates .NET bytecode, which uses the .NET just-in-time compiler to generate partially optimized native code; my backend generates Low-Level Virtual Machine code, which uses the LLVM optimizer and JIT compiler to produce optimized native code.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Q1&lt;/span&gt; [design, programming]&lt;br /&gt;A fairly simple and elegant RISC processor design and emulator. The Q1 began as an idea for a term project in computer architecture class to create a simple CPU and emulator; like Engram, the Q1 was conceived and work began prior to learning that we couldn't design the instruction set (the whole purpose of the Q1). However, I stuck with this one long enough to finish the basic instruction set architecture and create an emulator and sample programs (though not an assembler, which made it a huge pain to program). A number of the design decisions were &lt;a href="http://www.google.com/custom?domains=qstuff.blogspot.com&amp;amp;q=Q1&amp;amp;sa=Search&amp;amp;sitesearch=qstuff.blogspot.com&amp;amp;client=pub-7330245220228346&amp;amp;forid=1&amp;amp;ie=ISO-8859-1&amp;amp;oe=ISO-8859-1&amp;amp;cof=GALT%3A%23008000%3BGL%3A1%3BDIV%3A%23336699%3BVLC%3A663399%3BAH%3Acenter%3BBGC%3AFFFFFF%3BLBGC%3A336699%3BALC%3A0000FF%3BLC%3A0000FF%3BT%3A000000%3BGFNT%3A0000FF%3BGIMP%3A0000FF%3BFORID%3A1&amp;amp;hl=en"&gt;discussed&lt;/a&gt; on the blog.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Ray Tracer&lt;/span&gt; [programming]&lt;br /&gt;As with just about everybody who has ever taken a graphics course, I had to make a simple ray tracer. As this was only one assignment (and not a term project), the emphasis was kind of on the simple (there was no requirement for support of meshes, reflection/refraction, etc. However, I really ended up getting into this one, and added a substantial amount of additional features beyond those required in the assignment. Thanks to all my additions, it easily grabbed the top spot in the class.&lt;br /&gt;&lt;br /&gt;While I intended to, I never got around to writing much about the ray tracer and the various features I chose to implement (and why), though the &lt;a href="http://wiki.ecs.fullerton.edu/index.php/Justin_Olbrantz_Ray_Tracer"&gt;project page&lt;/a&gt; on the school wiki summarizes the features and shows them off with various screen shots.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;recMPQ&lt;/span&gt; [reverse-engineering, programming]&lt;br /&gt;recMPQ was a simple program to test some revere-engineering work on the MPQ format. The World of Warcraft Burning Crusade expansion added several new MPQ format features related to support for large archives (greater than 4 gigabytes). However, at the time no actual archives used these features. Consequently, I was forced to  rely on pure disassembly, without being able to look at properly-formed archives or even watch the game load an archive using these features. recMPQ was a program to make a large MPQ archive based on my disassembly findings, which I could then replace a BC archive with to observe whether the game was able to successfully load the archive (indicating I had properly used the new features). This information was ultimately added to my MoPaQ format specification.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;TextBreaker&lt;/span&gt; [programming]&lt;br /&gt;A system to identify the language of a block of text using artificial neural networks. This was my term project (and accompanying term paper) in artificial intelligence class, which integrated AI, my interest in linguistics, and my interest in biology all into one. Unfortunately, identifying languages isn't as easy as it sounds, and the project ended up being more educational - in the sense of revealing difficulties and what does and doesn't work - than remarkably successful at actually identifying text. Nevertheless, it did manage to impress the (undergraduate) class, the teacher (specializing in AI), and my grandpa (a professional linguist), and my teacher and grandpa both suggested that I continue work on it and submit my results to AI and linguistics journals.&lt;br /&gt;&lt;br /&gt;I never got around to cleaning up the source to release it (I did the whole term project in a week and a half, which made for very hackish code), but I did post the accompanying  &lt;a href="http://quantam.devklog.net/Orthographic%20Language%20Identification%20Using%20Artificial%20Neural%20Networks.pdf"&gt;Orthographic Language Identification Using Artificial Neural Networks&lt;/a&gt; paper back when I turned it in.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;StormDump&lt;/span&gt; [reverse-engineering, programming]&lt;br /&gt;A memory tracker and browser used to examine the memory use of Blizzard games. Unlike the benchmarking project mentioned above, which merely logged calls to the allocation functions, this project consisted of reverse-engineering of the memory allocation system itself, and the associated data structures. It logged each memory allocation made, and tracked how many allocations were made of given sizes and types, both at a particular time and in total, and allowed you to dump all memory allocated at a particular time via hotkeys. All of this was done by directly traversing the memory structures for the allocation system. I don't believe I ever gave this or the source out to anyone.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Watcher&lt;/span&gt; [programming]&lt;br /&gt;A simple program that logs all calls to API functions in various libraries that you specify using an configuration file. Version 1 of this hooked only functions specified in specified DLLs via INI files; some functions, such as the MPQ APIs, had hard-coded parameter-logging functions. Version 2 was capable of hooking all functions in all libraries and was intended to be scriptable to allow function-specific parameter logging for logged functions, though scriptability was never actually implemented.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;ZIC2RAW&lt;/span&gt; [reverse-engineering, programming]&lt;br /&gt;A project/program to extract the digital music files from the &lt;a href="http://en.wikipedia.org/wiki/3DO_Interactive_Multiplayer"&gt;3DO&lt;/a&gt; version of &lt;a href="http://en.wikipedia.org/wiki/Mega_race"&gt;Mega Race&lt;/a&gt;. The format actually ended up being quite trivial to reverse-engineer, though the files turned out to not be entirely self-contained - part of the music data was embedded in the game executable itself, and not stored in the separate music files. Apart from a tool to work with 3DO discs, all of the reverse-engineering for this was done with a hex editor.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-307827691849865288?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/307827691849865288/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=307827691849865288' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/307827691849865288'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/307827691849865288'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/01/bibliography-programming.html' title='Bibliography - Programming'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-8669654281754957531</id><published>2010-01-05T18:44:00.001-08:00</published><updated>2010-01-05T18:46:21.977-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Do I Speak WHAT?</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_9GysFr4NPa4/S0P5Dk5ewiI/AAAAAAAAAMQ/o9PpgoYjqH4/s1600-h/LanguagesSpoken.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 244px;" src="http://2.bp.blogspot.com/_9GysFr4NPa4/S0P5Dk5ewiI/AAAAAAAAAMQ/o9PpgoYjqH4/s400/LanguagesSpoken.gif" alt="" id="BLOGGER_PHOTO_ID_5423452216123900450" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Reference material: &lt;a href="http://en.wikipedia.org/wiki/HP-10C_series"&gt;HP 15C&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Zilog_Z80"&gt;z80&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8669654281754957531?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8669654281754957531/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8669654281754957531' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8669654281754957531'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8669654281754957531'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/01/do-i-speak-what.html' title='Do I Speak WHAT?'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_9GysFr4NPa4/S0P5Dk5ewiI/AAAAAAAAAMQ/o9PpgoYjqH4/s72-c/LanguagesSpoken.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-4313995346625888886</id><published>2010-01-03T13:23:00.000-08:00</published><updated>2010-01-03T13:25:58.524-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>Random Fact of the Day</title><content type='html'>In .NET, String.GetHashCode computes the hash code every time the function is called. This is slightly surprising given that Strings are immutable, and thus could easily compute the hash code on construct or on the first call to GetHashCode (although both of those options do have associated overhead).&lt;br /&gt;&lt;br /&gt;Someone I know believes that Java is the same way.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-4313995346625888886?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/4313995346625888886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=4313995346625888886' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4313995346625888886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4313995346625888886'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2010/01/random-fact-of-day.html' title='Random Fact of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-3435324181501937109</id><published>2009-12-28T19:55:00.000-08:00</published><updated>2009-12-28T19:55:28.260-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>&amp; Modern Things Part 3</title><content type='html'>So yeah, the Xbox 360 is pretty uninteresting, apart from the memory limitation. Fortunately, the third and final thing you can program with XNA is rather interesting: the &lt;a href="http://en.wikipedia.org/wiki/Zune"&gt;Zune&lt;/a&gt;. The Zune is Microsoft's answer to the &lt;a href="http://en.wikipedia.org/wiki/IPod"&gt;iPod&lt;/a&gt;: a portable music player. However, the Zune is also capable of running third-party programs through XNA. This makes it rather interesting, as it gives you the best taste of what it was like to program a console in the past (back before console CPUs were in the GHz and memory was in the hundreds of megs), as it has some of the same programming considerations (or at least moreso than the 360 or PC).&lt;br /&gt;&lt;br /&gt;There are a few different models of Zune with different capabilities, which can be separated into what I'll call the 'Zune' (the first several models, which are pretty much identical for our purposes), and the recent Zune HD.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/commons/5/54/Zune2%281%29.jpg"&gt;&lt;img style="cursor: pointer; width: 342px; height: 300px;" src="http://upload.wikimedia.org/wikipedia/commons/5/54/Zune2%281%29.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The Zune series is shown above. Members of the series vary in exact design, but all have a few common features. All models have a low-power ARM CPU, 64 megs of RAM, and has the ability to do basic bitmap graphics. They contain a 240x320 LCD screen in 3:4 aspect ratio (the screen size varies from 1.8 to 3.2 inches, diagonal), running at 30 FPS (some high-end models also support 60 FPS). For input, each has a circular pad as well as one button to each side of the pad.&lt;br /&gt;&lt;br /&gt;These features give the Zune a unique set of programming considerations. Obviously, the CPU is drastically less powerful than on the PC or Xbox 360. Games have a quota of 16 megs of RAM usage, in which both code and data must fit (although as this is only 1/4 of the total RAM of the Zune, garbage collection overhead is much less of a problem, and you should be able to use all 16 megs without seeing too much garbage collection slowdown). Graphics are limited to 2D sprite-based operations, and screen space is very limited (the Zune actually has a quite impressive display resolution for its screen size, but it's still tiny). Of course, the fact that this is a portable system means that battery life is also an issue. But perhaps the most tricky issue is the input system.&lt;br /&gt;&lt;br /&gt;The Zune is designed to be used standing up, as shown in the above picture. In this orientation, the screen is taller than it is wide. Control can use both thumbs, with one thumb on one button, and the other thumb shared between the circular pad and the second button. However, as games typically are designed around a screen that is wider than it is tall, this configuration comes off as somewhat unnatural, though some games are more appropriate for this than others (e.g. a top-down shooter would have no problems, here).&lt;br /&gt;&lt;br /&gt;Alternately, the Zune may be turned on its side, yielding the standard 4:3 aspect ratio used on everything prior to high-definition televisions and wide-screen monitors. The chief problem with this configuration, then, becomes control. Due to the button configuration of the Zune, this configuration allows only one thumb for input, shared between the circular pad and the two buttons. This has the effect of drastically reducing the potential complexity of gameplay input, as it's far more cumbersome to switch between buttons than to simply have a second thumb take care of one of them.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Microsoft_Zune_HD.jpg/800px-Microsoft_Zune_HD.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 300px;" src="http://upload.wikimedia.org/wikipedia/commons/thumb/4/4b/Microsoft_Zune_HD.jpg/800px-Microsoft_Zune_HD.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://en.wikipedia.org/wiki/Zune_HD"&gt;Zune HD&lt;/a&gt; is shown above. You could really call this the Zune 2 (or, if you're Nintendo, the Super Zune), as it's almost entirely different from the previously mentioned Zune series.  It's powered by an &lt;a href="http://en.wikipedia.org/wiki/Nvidia_Tegra"&gt;nVidia Tegra&lt;/a&gt; (2600), a system on a chip which both acts as an (ARM) CPU and a GPU capable of 3D graphics (although thus far XNA does not support 3D on the Zune HD). As far as I know, the amount of memory on the HD has not been published, though it's safe to say it has at least 64 megs RAM. While the screen is only 3.3 inches (about the same as the higher-end Zunes), the screen is now 480x272 (when laid sideways) in the HDTV 16:9 aspect ratio.&lt;br /&gt;&lt;br /&gt;Perhaps most significant, however, and the reason the Zune is much more interesting than the PC and Xbox 360, is the change in input system. As can be seen in the image, the Zune HD has &lt;span style="font-style: italic;"&gt;no&lt;/span&gt; buttons or other controls. Instead, the HD features two new input methods: a multi-touch display and an accelerometer.&lt;br /&gt;&lt;br /&gt;For those not familiar with it, multi-touch displays are a type of touch-screen, which take as input a point on the screen and the pressure exerted on the screen at that point. Multi-touch takes this to the next level by allowing multiple points of contact, including tracking of movement of each point. This allows for very flexible and powerful input, permitting such interfaces as "point and click" via pressing the screen at a point, dragging and dropping, and things such as gestures. This even allows interfaces such as the one seen in Minority Report (and other sci-fi-ish depictions), where multiple points of contact with the touch screen can be used to grab and move, rotate, or resize items on screen (this type of interface exists in the &lt;a href="http://en.wikipedia.org/wiki/Microsoft_Surface"&gt;Microsoft Surface&lt;/a&gt; and other multi-touch devices; also, be sure to check out the Dungeons and Dragons on Surface &lt;a href="http://blogs.msdn.com/surface/archive/2009/12/16/new-gameplay-video-with-d-d-on-surface.aspx"&gt;demonstration&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;You might not be able to guess what an accelerometer is, based only on the name: obviously it measures acceleration, but unless you're into physics, you probably wouldn't make the connection with gravity. Technically, holding an object in air (as opposed to letting it free-fall) requires an upward force to be applied to the object, and a force produces acceleration. An accelerometer measures this acceleration against the force of gravity; in other words, an accelerometer measures which direction is up, based on the orientation of the device. Of course, it also detects other types of acceleration, such as movement in space, as well. Between the possibilities, this allows a number of interesting (and impossible, with traditional input methods) input systems, such a basing the in-game camera on position and/or orientation of the Zune, actions triggered by bumping or shaking, etc.&lt;br /&gt;&lt;br /&gt;Microsoft makes the multi-touch screen and accelerometer available in XNA through the XNA &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=48f7ba37-8ba7-4d16-8873-0b7f83ef77f9&amp;amp;displaylang=en"&gt;Zune Extensions&lt;/a&gt; addon. Once you've downloaded that, search the help for Zune HD Input Overview for general information about support. After that, zunezune.org has posted a helpful simple "game" that demonstrates multi-touch and accelerometer: the code is available &lt;a href="http://zunezune.org/index.php?ArticleID=23"&gt;here&lt;/a&gt;, and a video of the program in action is below. Finally, Platformer: Adding Touch Support (also in Extensions help) is a tutorial that shows you how to add multi-touch and accelerometer support to the platformer starter kit.&lt;br /&gt;&lt;br /&gt;&lt;object height="349" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/75hAEip50ww&amp;amp;border=1&amp;amp;color1=0x3a3a3a&amp;amp;color2=0x999999&amp;amp;hl=en_US&amp;amp;feature=player_embedded&amp;amp;fs=1"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowScriptAccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/75hAEip50ww&amp;amp;border=1&amp;amp;color1=0x3a3a3a&amp;amp;color2=0x999999&amp;amp;hl=en_US&amp;amp;feature=player_embedded&amp;amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" height="349" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-3435324181501937109?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/3435324181501937109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=3435324181501937109' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3435324181501937109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3435324181501937109'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/12/modern-things-part-3.html' title='&amp; Modern Things Part 3'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6027691788343831943</id><published>2009-12-23T12:23:00.000-08:00</published><updated>2009-12-23T12:23:00.512-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>&amp; Modern Things Part 2</title><content type='html'>So, after looking a bit at several (very) old game systems, how about we look at a couple of the new ones. Though in reality, the &lt;a href="http://en.wikipedia.org/wiki/Xbox_360_hardware"&gt;XBox 360&lt;/a&gt; is actually pretty boring; which is to say that it's more or less a modern computer.&lt;br /&gt;&lt;br /&gt;The 360's &lt;a href="http://en.wikipedia.org/wiki/Xenon_%28processor%29"&gt;Xenon&lt;/a&gt; CPU is a pretty typical &lt;a href="http://www.ibm.com/developerworks/power/library/pa-fpfxbox/"&gt;incarnation&lt;/a&gt; of the &lt;a href="http://en.wikipedia.org/wiki/PowerPC"&gt;PowerPC&lt;/a&gt; line used in older Macs, and is related to the &lt;a href="http://en.wikipedia.org/wiki/PlayStation_3_hardware"&gt;Playstation 3&lt;/a&gt;'s &lt;a href="http://en.wikipedia.org/wiki/Cell_%28microprocessor%29"&gt;Cell&lt;/a&gt; CPU (although the Cell has a very unusual architecture resembling a &lt;a href="http://qstuff.blogspot.com/2007/07/types-of-multiprocessors.html"&gt;cluster on a chip&lt;/a&gt;, and differs quite a bit from other PowerPC chips - or most CPUs, for that matter). The PowerPC line, the low-end portion of the larger &lt;a href="http://en.wikipedia.org/wiki/Power_Architecture"&gt;Power&lt;/a&gt; line, are &lt;a href="http://en.wikipedia.org/wiki/Reduced_instruction_set_computer"&gt;RISC&lt;/a&gt; processors with simple instructions limited primarily to operations on registers, in contrast to the &lt;a href="http://en.wikipedia.org/wiki/Complex_instruction_set_computer"&gt;CISC&lt;/a&gt; x86 and the CPUs of the 2600, NES, and SNES, which tend to use many instructions that operate on memory data.&lt;br /&gt;&lt;br /&gt;The Xenon is composed of three symmetric 64-bit cores with a shared L2 cache. Each core executes two threads simultaneously, and contains (among the expected things) a &lt;a href="http://en.wikipedia.org/wiki/SIMD"&gt;SIMD&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/AltiVec"&gt;vector unit&lt;/a&gt; for significant math performance (although if you're using XNA you won't have access to the vector unit). The only remotely noteworthy part of the CPU is the fact that unlike some other PowerPC varieties (and all Intel CPUs for quite a while, now), execution is in-order, meaning that it must pause execution of a thread when a slow I/O operation is required; the assumption then is that the number of threads executing at a time (2 per core) will reduce the impact of individual stalls.&lt;br /&gt;&lt;br /&gt;The &lt;a href="http://en.wikipedia.org/wiki/Xenos_%28graphics_chip%29"&gt;Xenos&lt;/a&gt; GPU is also fairly uninteresting. It's a custom ATI 3D GPU designed specifically for the XBox 360 and optimized for console games, though a lot of it resembles common PC GPUs of the same vintage. It supports the DirectX 9 &lt;a href="http://en.wikipedia.org/wiki/High_Level_Shader_Language"&gt;Shader Model&lt;/a&gt; 3, although it contains some custom extensions that provide some of the features new in DirectX 10 Shader Model 4 (though the details may differ), such as the &lt;a href="http://en.wikipedia.org/wiki/Unified_Shader_Architecture"&gt;unified shader architecture&lt;/a&gt;. It also has dedicated hardware to provide 4x anti-aliasing &lt;a href="http://techreport.com/etc/2005q2/xbox360-gpu/index.x?pg=2"&gt;for "free"&lt;/a&gt; (as opposed to the performance penalty that normally occurs with anti-aliasing) and &lt;a href="http://www.beyond3d.com/content/articles/4/5"&gt;optimized z-only rendering&lt;/a&gt;. Finally, after all the fancy rendering is done, the 360 supports several (television) output resolutions from 640x480 (standard TV) to 1920x1080 (highest HD widescreen).&lt;br /&gt;&lt;br /&gt;But the most noteworthy parts are the ones we haven't seen before (at least in this series of posts).&lt;br /&gt;&lt;br /&gt;Some versions of the 360 come with a hard drive of varying sizes. In addition to saved games (which can also be stored on memory cards or internal flash memory, on models without the hard drive), this drive is used for game caching (hard drives are faster than DVDs) and optional downloadable content. It's also used to store the XBox compatibility software that allows the 360 to emulate games for the original XBox.&lt;br /&gt;&lt;br /&gt;Finally, all XBox 360s come with the ability to connect to the internet (wired ethernet ports are standard, with a wireless addon), especially for the purpose of connecting to the &lt;a href="http://en.wikipedia.org/wiki/Xbox_Live"&gt;XBox Live service&lt;/a&gt;. Live is a social platform that covers a wide range of services (although some require a paid subscription to Live), including friends lists and communication; multiplayer matchmaking and play; game achievements that allow your friends to see your gaming accomplishments; voice and video chat with friends; downloadable bonus game content; the &lt;a href="http://en.wikipedia.org/wiki/Xbox_Live_Marketplace"&gt;Live Marketplace&lt;/a&gt;, where you can purchase and download addons and entire games (including XNA games) and other content (e.g. movies); and several major third-party web services such as &lt;a href="http://en.wikipedia.org/wiki/Netflix"&gt;Netflix&lt;/a&gt; streaming movies and &lt;a href="http://en.wikipedia.org/wiki/Last.fm"&gt;Last.fm&lt;/a&gt; steaming music.&lt;br /&gt;&lt;br /&gt;So, that's the hardware and the platform. But what's it like to program? Well, thanks to the surreal veil of secrecy surrounding consoles in general, that much isn't really common knowledge, and I'm not entirely sure. Development is in C or C++, probably with the Intel C++ compiler. The 360 uses a custom operating system (so they say) that supports at least some approximation of the Windows API and DirectX; while the OS does not use the same driver system Windows normally uses, the CPU is probably the only piece of hardware in the system programmers are supposed to directly access, with other hardware abstracted through the Windows or DirectX APIs or some such. Given this, if Microsoft is smart, they made it as similar to programming on Windows as possible, so that developers can transition from the PC to the 360 with minimal education. Though one thing that will definitely have to differ is the compiler intrinsics, for things such as vector math (perhaps the same intrinsics that were used on the PowerPC Mac) and multithreading-related things (e.g. memory barriers; &lt;a href="http://www.google.com/custom?domains=qstuff.blogspot.com&amp;amp;q=memory+barriers&amp;amp;sa=Search&amp;amp;sitesearch=qstuff.blogspot.com"&gt;remember those&lt;/a&gt;?).&lt;br /&gt;&lt;br /&gt;The situation is different if you're using XNA. In this case programming the 360 is almost identical to programming the PC via XNA. Programming is done in C#, and run on the .NET compact framework. The runtime libraries consist of a subset of the .NET class library and the additional features supplied by the XNA class library. No hardware is directly accessible; the CPU and memory are hidden behind the .NET framework, and graphics and sound hardware can only be accessed through the XNA class library (as far as I know you can't directly access DirectX through XNA, at least on the 360).&lt;br /&gt;&lt;br /&gt;But regardless of how you program it, perhaps the most noteworthy difference between programming a PC and the 360 is the memory limitation. While on PCs it's always been cheapest to just make your users buy more memory, on consoles it's frequently the case that you have to actually spend development manpower shaving off memory usage to make your game fit in the console's memory (at least for large, complex games). The 360 has 512 megs of memory. While this may not sound so bad at first, you have to realize that this is common memory, shared by both the CPU and the graphics system (though at least the OS probably takes up drastically less memory on the 360 than on the PC). Compared to PC games that typically take north of a gig of main memory and 512 megs video memory, 512 megs starts to look pretty small (for the curious, the Playstation 3 is comparable: 256 megs main memory and 256 megs graphics memory).&lt;br /&gt;&lt;br /&gt;This is especially true in the case of XNA. As &lt;a href="http://qstuff.blogspot.com/2009/12/modern-things-part-1.html"&gt;stated previously&lt;/a&gt;, thanks to garbage collection, you can only use 30-40% of the total system memory before you start seeing a substantial decrease in available processing power due to garbage collection; on the 360 this comes out to something like 64-128 megs, depending on how much memory is used for graphics. Fortunately, there's a way to deal with this penalty: avoid garbage collection entirely. Garbage collection is triggered when a memory allocation fails due to there not being enough unallocated memory to perform the allocation; the framework then performs garbage collection to look for memory that was allocated but is no longer being used, and can be freed to make room for the new allocation.&lt;br /&gt;&lt;br /&gt;In other words, if you can avoid allocating memory during gameplay, you can prevent garbage collection (you could also &lt;a href="http://msdn.microsoft.com/en-us/library/system.gc.collect.aspx"&gt;manually cause&lt;/a&gt; the framework to do garbage collection at times which are convenient, such as during loading or pausing); this is optimization 101: the fastest code is the code that isn't executed. Use structs, which are allocated on the stack or within the containing memory structure, &lt;a href="http://msdn.microsoft.com/en-us/library/aa664472%28VS.71%29.aspx"&gt;rather than classes&lt;/a&gt;, which are allocated out of the heap; use allocation-minimizing algorithms and data structures, such as an &lt;a href="http://en.wikipedia.org/wiki/Hash_table#Open_addressing"&gt;open-addressing hash table&lt;/a&gt; (e.g. &lt;a href="http://msdn.microsoft.com/en-us/library/xfhwa508.aspx"&gt;Dictionary&lt;/a&gt;), where the hash table is an array of entries, rather than an &lt;a href="http://en.wikipedia.org/wiki/Hash_table#Separate_chaining_with_list_heads"&gt;array of linked lists&lt;/a&gt; or a binary tree (e.g. &lt;a href="http://msdn.microsoft.com/en-us/library/f7fta44c.aspx"&gt;SortedDictionary&lt;/a&gt;), which must allocate memory for each entry; use reasonable reserve sizes for structures so the structure isn't likely to need to be reallocated during gameplay; use &lt;a href="http://en.wikipedia.org/wiki/Free_list"&gt;free lists&lt;/a&gt; as much as possible; use specific enumerators rather than IEnumerator; etc. - anything that can significantly reduce the need to allocate memory.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6027691788343831943?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6027691788343831943/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6027691788343831943' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6027691788343831943'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6027691788343831943'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/12/modern-things-part-2.html' title='&amp; Modern Things Part 2'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-9103290286142609309</id><published>2009-12-18T19:00:00.000-08:00</published><updated>2009-12-18T19:12:51.773-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>&amp; Modern Things Part 1</title><content type='html'>One thing that has always kind of mystified me is the degree of inaccessibility maintained about video game console development. For almost every single video game console in history, getting access to the manufacturer's developer documentation and hardware requires that you be licensed (and it sucks to be you if the manufacturer doesn't like you) and have a large sum of money for the development kits; for most systems, the accessibility of the system to lone hobbyists has been 0.&lt;br /&gt;&lt;br /&gt;Of course, eventually the system, if there's enough interest, is reverse-engineered, and unofficial documentation is put up on the internet (and perhaps followed by law suits). But such documentation is usually incomplete, inaccurate, or just plain badly written, and there's almost always anti-piracy lockout mechanisms that prevent you from actually running any code you manage to write on the system itself.&lt;br /&gt;&lt;br /&gt;This is a strikingly odd decision, and seemingly self-destructive. Many software companies turn a blind eye to piracy among college students because they realize that students pirating their programs in college, when they couldn't afford to buy the programs, anyway, makes them more likely to use them professionally, when they do have money to purchase the programs. Some companies even give away their programs to students for educational purposes, for the very same reason: more student users that get the program for free means more buyers after graduation. Economically, it's a simple business investment, trading theoretical income now, which they couldn't collect anyway, for greater actual income later.&lt;br /&gt;&lt;br /&gt;This situation on consoles is no different. If you promote hobbyist development on your game console, that increases the probability that those hobbyists will develop on your console when they go pro. This is especially applicable considering that the modern game console business model is to sell the consoles at a loss, then make up that loss in licensing of games; thus, every additional game developed for your system equals more money for you. Ultimately, I suspect the reason for this odd behavior lies in the lockout mechanism: in order to allow hobbyists to develop for the console, the console cannot have a lockout mechanism, which would make it much easier to pirate games.&lt;br /&gt;&lt;br /&gt;Anyway, there are only a couple exceptions to this rule, that I know of. Sony published a mini developer kit for the &lt;a href="http://en.wikipedia.org/wiki/PlayStation"&gt;Playstation&lt;/a&gt;, called the &lt;a href="http://en.wikipedia.org/wiki/Net_Yaroze"&gt;Net Yaroze&lt;/a&gt;, for about a grand, which included a black development version of the system (lacking the lockout hardware), various documentation (I don't know if this was the same or inferior to the professional documentation), some run-time libraries (probably inferior to the professional kits) and software to get custom code onto the Yaroze. Of course, anything you write could only be run by people with their own Yaroze, due to the lockout system.&lt;br /&gt;&lt;br /&gt;Very surprisingly, only in the last couple years has anyone actually targeted non-professionals as serious developers for their system. Of course I'm talking about &lt;a href="http://en.wikipedia.org/wiki/Microsoft_XNA"&gt;XNA&lt;/a&gt; (&lt;a href="http://msdn.microsoft.com/xna/"&gt;official site&lt;/a&gt;). XNA is a free game programming framework built on top of the &lt;a href="http://en.wikipedia.org/wiki/.NET_Framework"&gt;.NET platform&lt;/a&gt;. Games are written in C# in Visual C#, and make use of the .NET and XNA class libraries. The .NET libraries  (a subset, to be precise) provide general support code such as data structures and multi-threading, and the XNA libraries cover hardware access, such as graphics and sound, and various support routines too game-specific for the .NET libraries, such as quaternions and interpolated curves. Use of the .NET framework also provides things such as garbage collection, that make programming easier and faster; the use of non-native code and APIs also means that, if code is written carefully, a single game can be compiled and run on all three platforms XNA supports: Windows, &lt;a href="http://en.wikipedia.org/wiki/Xbox_360"&gt;Xbox 360&lt;/a&gt;, and the &lt;a href="http://en.wikipedia.org/wiki/Zune"&gt;Zune&lt;/a&gt;  (the fine print: development on the 360 requires a &lt;a href="http://creators.xna.com/en-US/membership"&gt;Creators Club Premium subscription&lt;/a&gt;; membership is available to anyone, but costs $100/year).&lt;br /&gt;&lt;br /&gt;Unlike the completely unrelated, professional Xbox 360 Software Developer Kit, XNA is targeted specifically at hobbyists and independent developers (e.g. a person who writes a small game and wants to sell it for cheap). Microsoft runs an &lt;a href="http://creators.xna.com/en-US/"&gt;active community site&lt;/a&gt; containing Microsoft-written &lt;a href="http://creators.xna.com/en-US/education/catalog/"&gt;code samples, tutorials&lt;/a&gt;, and &lt;a href="http://creators.xna.com/en-US/education/starterkits/"&gt;starter kits&lt;/a&gt; (e.g. a &lt;a href="http://creators.xna.com/starterkit/roleplayinggame"&gt;2D RPG&lt;/a&gt; and a &lt;a href="http://creators.xna.com/starterkit/racinggame"&gt;3D racing game&lt;/a&gt;), and &lt;a href="http://forums.xna.com/forums/"&gt;forums&lt;/a&gt; where both hobbyists and XNA developers post. There are also third-party XNA tutorial/code sites, though Ziggyware, the largest and best, imploded a ways back (humorously, &lt;a href="http://www.google.com/search?hl=en&amp;amp;lr=&amp;amp;q=Justin+Olbrantz+site%3Aziggyware.com&amp;amp;aq=f&amp;amp;oq=&amp;amp;aqi="&gt;according to Google&lt;/a&gt;, Ziggyware and a few others had posted the presentation I wrote on kd-trees as part of my &lt;a href="http://qstuff.blogspot.com/2008/05/spatial-sorting-with-kd-trees-part-1.html"&gt;graphics term project&lt;/a&gt;, prior to the site going under).&lt;br /&gt;&lt;br /&gt;Once a game is finished, in addition to distributing the source and/or binaries manually, finished games can be submitted to several places, depending on platform. Free Windows games may be submitted to the XNA community website for download. Finished games can also be submitted to the &lt;a href="http://en.wikipedia.org/wiki/Xbox_Live_Marketplace"&gt;Xbox Live Marketplace&lt;/a&gt;, where they can be downloaded, either for free or for sale (whatever you decide on), by anyone who has an Xbox 360 (a Creators Club subscription is not required to play games published on the Marketplace). To say that again: you can sell your amateur Xbox games for cash through Live Marketplace, right next to professional downloadable games.&lt;br /&gt;&lt;br /&gt;Of course, this isn't without its caveats. XNA doesn't allow you to directly access the hardware, or use the same low-level API professional developers use from a natively-executed (after compiling) language like C++. This means that XNA games cannot compete in sheer speed and power with professionally-developed games. It also means that you may not be able to access 100% of the features of the hardware, where XNA only exposes a portion of the feature set; one very notable omission is the ability to use the Xbox 360's &lt;a href="http://en.wikipedia.org/wiki/AltiVec"&gt;vector math unit&lt;/a&gt;, a fact that drastically reduces the performance potential for some types of calculations.&lt;br /&gt;&lt;br /&gt;Second is the fact that it's a .NET platform. While this choice was good from an ease of programming perspective (&lt;a href="http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29"&gt;garbage collection&lt;/a&gt; is easier to program and less prone to various coding errors, especially given that most of the people coding on XNA will be amateurs and thus may not be very good), it's not so good from a performance perspective. Perhaps the most stereotypical problem for garbage-collected systems like Java or the .NET platform is that garbage collection is &lt;a href="http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29#Disadvantages"&gt;far from free&lt;/a&gt;, both in terms of CPU and memory. If you plot the proportion of time the CPU spends collecting garbage (instead of, you know, actually running the program) against memory usage, you'll find that after a certain threshold cost grows exponentially. &lt;a href="http://www.cs.umass.edu/%7Eemery/pubs/gcvsmalloc.pdf"&gt;One study&lt;/a&gt; found that, when memory utilization is at 20%, garbage collection is no more expensive (and maybe even faster) than explicit allocation/deletion, but costs rise quickly from there: garbage collection is 17% slower at 33% memory usage, 70% slower at 50% memory usage, and as you approach 100% memory utilization garbage collection approaches 100% of total CPU time.&lt;br /&gt;&lt;br /&gt;A third major point of concern is that the XNA framework on the Xbox 360 does not have the full .NET framework/compiler, but only the &lt;a href="http://en.wikipedia.org/wiki/.NET_Compact_Framework"&gt;Compact Framework&lt;/a&gt;. This version is designed for hardware that doesn't have a lot of memory or processing power (especially things like PDAs), and offers reduced memory and CPU overhead at the price of sub-optimal execution speed. Of the various optimizations performed by the full-fledged .NET framework, only a subset are performed by the compact framework; for example, inlining is restricted, virtual function calls are implemented in a more compact but slower manner, and both the framework and garbage collection algorithm are just dumber in general, to name a few issues (see &lt;a href="http://blogs.msdn.com/netcfteam/archive/2005/05/04/414820.aspx"&gt;here&lt;/a&gt; for a more lengthy list).&lt;br /&gt;&lt;br /&gt;However, making decisions is easy when there's only one option, and if you're a hobbyist wanting to code for a modern video game console, that option is XNA. Even if you're not interested in consoles, XNA still provides a convenient and free game development platform, designed specifically with hobbyists in mind. It also opens the possibility of making a bit of money off your amateur games prior to going pro.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-9103290286142609309?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/9103290286142609309/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=9103290286142609309' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/9103290286142609309'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/9103290286142609309'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/12/modern-things-part-1.html' title='&amp; Modern Things Part 1'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-8294336532407428058</id><published>2009-12-15T14:24:00.000-08:00</published><updated>2009-12-15T14:27:56.351-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>&amp; Moral Panics</title><content type='html'>One topic that came up rather suddenly in IRC is the topic of the irrationality of humans when a person feels wronged. The particular topic in chat was that, I'm told, you should never, ever touch leaked materials, such as the &lt;a href="http://www.microsoft.com/presspass/press/2004/Feb04/02-12windowssource.mspx"&gt;Windows source&lt;/a&gt; or &lt;a href="http://www.crunchgear.com/2009/11/06/siren-gif-microsoft-cofee-law-enforcement-tool-leaks-all-over-the-internet/"&gt;COFEE&lt;/a&gt;, because this tends to send companies (especially the one that produced said thing) into moral panics and refuse to ever hire you.&lt;br /&gt;&lt;br /&gt;Think about this for a moment; a little bit of rational thought concludes that this is highly irrational behavior, reminiscent of the &lt;a href="http://en.wikipedia.org/wiki/Pointy-Haired_Boss"&gt;Pointy-Haired Boss&lt;/a&gt; (is there a Dilbert strip on this topic, I wonder?). If you were Microsoft, for instance, and you were looking to hire a programmer for the Windows team (although this could also apply to other parts as well), the #1 most desirable candidate for you is the one who has played extensively with the leaked Windows source, all other things being equal. Not only would categorically refusing to hire such a person result in no benefit, but it would materially harm you as a company, by refusing the candidate most beneficial to you. This is a case where moral outrage contradicts reason, and acting on that outrage results in self-destructive behavior that does more harm than good; or, as the saying goes, cutting off your nose to spite your face.&lt;br /&gt;&lt;br /&gt;An alternate form of this is observed extensively in the copyright industries, who have a long history of various licensing and technology blunders with a detrimental effect to their own sales in the name of fighting piracy (and the goal of fighting piracy is, you know, to &lt;span style="font-style: italic;"&gt;increase&lt;/span&gt; sales). In this case the moral outrage is provoked by a fixation on the amount of piracy; this is a fundamentally flawed measurement. The entire purpose of business is to maximize profit, and that is concerned (usually) solely with sales: reducing piracy (if you can even manage that) is of no benefit if doing so does not produce a net increase in sales at the same time; whatever the exact number of pirated copies may be is entirely irrelevant. And if you haven't managed to boost sales in the process, you're all the worse off because you're already out the money you spent trying to fight piracy.&lt;br /&gt;&lt;br /&gt;(for those wondering, yes, the term "moral panics" is from &lt;a href="http://moralpanicsandthecopyrightwars.blogspot.com/"&gt;Patry&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8294336532407428058?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8294336532407428058/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8294336532407428058' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8294336532407428058'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8294336532407428058'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/12/moral-panics.html' title='&amp; Moral Panics'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6373758708999178569</id><published>2009-12-13T16:32:00.000-08:00</published><updated>2009-12-13T16:34:28.679-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='games'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>&amp; Even Older Things</title><content type='html'>On Friday I went to a free, open presentation at University of California Irvine. Normally I wouldn't even mention such a thing on the blog, but it just so happened that a significant part of of presentation was about the hardware of the &lt;a href="http://en.wikipedia.org/wiki/Atari_2600"&gt;Atari 2600&lt;/a&gt;, a game console launched in 1977, 6 years before the Nintendo (NES). As this fits right in with &lt;a href="http://qstuff.blogspot.com/2009/08/very-old-things-part-1.html"&gt;a&lt;/a&gt; &lt;a href="http://qstuff.blogspot.com/2009/08/very-old-things-part-2.html"&gt;series&lt;/a&gt; &lt;a href="http://qstuff.blogspot.com/2009/08/very-old-things-part-3.html"&gt;of&lt;/a&gt; &lt;a href="http://qstuff.blogspot.com/2009/12/almost-as-old-things.html"&gt;posts&lt;/a&gt; on this blog, I figured I might as well write about it.&lt;br /&gt;&lt;br /&gt;Interestingly, the 2600 used almost the same CPU (the &lt;a href="http://en.wikipedia.org/wiki/MOS_Technology_6507"&gt;6507&lt;/a&gt;) as the NES (&lt;a href="http://en.wikipedia.org/wiki/MOS_Technology_6502"&gt;6502&lt;/a&gt;) and &lt;a href="http://en.wikipedia.org/wiki/Commodore_64"&gt;Commodore 64&lt;/a&gt; computer (&lt;a href="http://en.wikipedia.org/wiki/MOS_Technology_6510"&gt;6510&lt;/a&gt;). According to Wikipedia, the 6507 was a smaller version of the NES's 6502, while the 6510 was an expanded version of the 6502 . The 6502 supported 64 KB of address space (16-bit addressing), while the 6507 supported 8 KB (13-bit addressing); the 6502 also supported (external) hardware interrupts (the vertical blank interrupt, in the case of the NES), while the 6507 did not.&lt;br /&gt;&lt;br /&gt;In contrast to the NES's 2 KB and SNES's 128 KB, the 2600 had an amazing 128 &lt;span style="font-style: italic;"&gt;bytes&lt;/span&gt; of RAM (although more could be added on cartridges, for a manufacturing price). Early 2600 games came in 2 KB ROMs, although the system supported up to 32 KB with bank switching (4 KB at a time); in comparison, NES games ranged from (I think) 32 KB to 768 KB (also with bank switching: 32 KB at a time), although in theory it could support more.&lt;br /&gt;&lt;br /&gt;But by far the most "interesting" thing about the system was the &lt;a href="http://en.wikipedia.org/wiki/Television_Interface_Adapter"&gt;graphics system&lt;/a&gt;. Unlike the NES, SNES, and pretty much all consoles and computers made in the last three decades, the 2600 had &lt;span style="font-style: italic;"&gt;no&lt;/span&gt; video RAM to speak of. Instead of storing on-screen image data in video memory which is then composed by the graphics chip and output to the display, on the 2600 the video was drawn actively, one line at a time; by "actively" I mean that the game had to compose each line as it was drawn by the television. Each line, 160 pixels wide, was composed of 24 two-color background blocks, 2 eight-bit single-color bitmap sprites, 2 single-color line "missiles" whose colors mirror those of the sprites, and a line "ball" that was much like the missiles, but was the color of the background.&lt;br /&gt;&lt;br /&gt;However, while the hardware was very (very) limited, the ability (or necessity, in this case) to change the screen contents while drawing was underway provided some flexibility for the clever programmer (just like with the NES and SNES). Clever use of the missiles and ball, changing each scan line, allowed for more complex graphics than you'd imagine given the hardware capabilities. By changing the sprite configuration you could have more than two sprites, though having more than two sprites on the same scan line required alternating between them each frame, resulting in flicker. Alternating palettes allowed the system to display 4 different colors on each line (out of a total of 128), as well as multicolored sprites and backgrounds. Clever use of the missiles and ball allowed for additional sprites per line, or multi-color and non-block backgrounds. Developers even found that they could expand the background to a full 48 blocks (the background is 48 blocks wide, but the background is only 24 bits, describing the left half of the screen; the right side is formed by repeating or mirroring the left side) by modifying the background registers halfway through the line.&lt;br /&gt;&lt;br /&gt;Finally, the 2600 had sound analogous but inferior to the NES's. It had two channels of sound, one generating a square wave of varying pitch, the other white noise. In comparison, the NES had five channels: 2 square wave (used to approximate most melodic instruments in music), one triangle wave (often for bass or low-frequency strings), a noise channel (used for drums and other percussion), and a waveform channel (I'm not familiar with any instances of this being used by games).&lt;br /&gt;&lt;br /&gt;Pac Man, showing off more than two sprites and 48-block-wide backgrounds:&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/en/5/54/A2600_Pitfall.png"&gt;&lt;br /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/en/thumb/d/dc/Pac-Man_Atari_2600_footage.ogv/mid-Pac-Man_Atari_2600_footage.ogv.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 300px;" src="http://upload.wikimedia.org/wikipedia/en/thumb/d/dc/Pac-Man_Atari_2600_footage.ogv/mid-Pac-Man_Atari_2600_footage.ogv.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Pitfall, showing off multi-colored sprites and backgrounds, as well as (possibly) non-block backgrounds:&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://upload.wikimedia.org/wikipedia/en/5/54/A2600_Pitfall.png"&gt;&lt;img style="cursor: pointer; width: 320px; height: 226px;" src="http://upload.wikimedia.org/wikipedia/en/5/54/A2600_Pitfall.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6373758708999178569?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6373758708999178569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6373758708999178569' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6373758708999178569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6373758708999178569'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/12/even-older-things.html' title='&amp; Even Older Things'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-2243924290324198835</id><published>2009-12-04T19:05:00.000-08:00</published><updated>2009-12-04T19:05:42.149-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><title type='text'>Random Fact of the Day</title><content type='html'>&lt;a href="http://www.exactaudiocopy.de/"&gt;Exact Audio Copy&lt;/a&gt;, like some similar programs (I know older versions of Nero are like this) can be made to work on a Windows limited user account, but it requires a couple of things.&lt;br /&gt;&lt;br /&gt;First, you have to make the DAT files in the EAC folder writable by all users (or at least those you want to be able to use it).&lt;br /&gt;&lt;br /&gt;Second, you have to enable low-level access to the disk drive for limited users. The easiest and least dangerous (in terms of downloading software from who knows where) method of doing this is to simply use &lt;span style="text-decoration: underline;"&gt;&lt;/span&gt;&lt;a href="http://www.nero.com/enu/support-nero6-tools-utilities.html"&gt;Nero BurnRights&lt;/a&gt; (search down on the page), and it will allow you to set this option; note that you don't need to actually have Nero to use this program. Of course you'll have to install it and run it as admin, but once you set the option you'll be able to use EAC (and other similar programs) from any user.&lt;br /&gt;&lt;br /&gt;Finally, make sure EAC is set to use the Native Win32 Interface (EAC Options-&gt;Interface); this should be the default, but who knows.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-2243924290324198835?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/2243924290324198835/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=2243924290324198835' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2243924290324198835'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2243924290324198835'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/12/random-fact-of-day.html' title='Random Fact of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-7379613110072709061</id><published>2009-12-03T13:05:00.000-08:00</published><updated>2009-12-03T13:09:10.630-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>&amp; Almost as Old Things</title><content type='html'>Recently I've had the whim to play through &lt;a href="http://en.wikipedia.org/wiki/Final_Fantasy_6"&gt;Final Fantasy 6&lt;/a&gt; (3 in the US) again, and have been doing so on an (&lt;a href="http://en.wikipedia.org/wiki/Super_Nintendo"&gt;SNES&lt;/a&gt;) emulator. I'm currently about to start the last level, but that's beside the point of this post. While playing, I thought I'd take a look at the SNES hardware and write a blog post about it, given that I'd &lt;a href="http://qstuff.blogspot.com/2009/08/very-old-things-part-1.html"&gt;already looked&lt;/a&gt; at the NES hardware - though not anything half so extensive as what I did with the NES, just a look at the basic hardware. What I found actually surprised me. As it turns out, the SNES really is the Super NES; that is, it has very similar hardware, only better.&lt;br /&gt;&lt;br /&gt;First of all, the &lt;a href="http://en.wikipedia.org/wiki/Ricoh_5A22"&gt;CPU&lt;/a&gt; is a generational upgrade to the &lt;a href="http://en.wikipedia.org/wiki/Ricoh_2A03"&gt;NES' CPU&lt;/a&gt;, bigger and better. The CPU is now 16-bit (as opposed to the NES' 8-bit CPU), but has essentially the same instruction set (with some augmentations). The CPU is still CISC, sporting the same three general registers (an accumulator and two index registers) and operating on an accumulator register using the contents of memory. However, the CPU now has much greater flexibility in memory access, with a 24-bit pointer register and the ability to access memory relative to the stack pointer*. It also now has multiply and divide instructions, as well as a few other things. But deep down, it's the very same instruction set architecture, and in fact has an 8-bit compatibility mode that lets it directly execute code from the original NES CPU.&lt;br /&gt;&lt;br /&gt;*Both of these features were conspicuous absent in the NES, as I believe I noted. As the NES only had 8-bit registers, it had no way to hold pointers (which were 16 bits) in registers; to make use of pointers the NES had an indirect addressing mode where the CPU would write a pointer to memory 8 bits at a time, and then had an instruction to load/store a value through that pointer (think "mov reg, [memory]"). While the NES did have a stack, it had only push and pop instructions, and lacked the ability to access data relative to the stack pointer, preventing use of the stack to pass parameters or store local variables; consequently, parameters and local variables were assigned fixed memory addresses, and the stack was rarely used.&lt;br /&gt;&lt;br /&gt;The situation is somewhat similar in the &lt;a href="http://en.wikipedia.org/wiki/Super_Nintendo#Video"&gt;graphics system&lt;/a&gt;. While the graphics chip is drastically more powerful than the NES', it's based on the same concept of background layers and sprites, all drawn from a (larger) bank of 8x8 tiles. The SNES supports twice as many sprites as the NES (and a lot more per line) and sprites can be much larger (up to 64x64, compared to 8x16 on the NES), with 16 colors each (compared to 4, including transparent, on the NES); but perhaps the most interesting improvement is that there are now 4 background layers, and they can be combined via various raster operations in many interesting ways.&lt;br /&gt;&lt;br /&gt;To illustrate this, take a look at this picture: a typical shot from a battle. The SNES supports 8 different graphics modes. For the most part the difference between the 8 is the number of layers and how many colors each layer supports (presumably this is due to it being too expensive to put enough video memory in to allow full color from all layers at once). In this scene I'm guessing that it's using mode 3 ("3 layers, two using 16-color palettes and one using 4-color palettes"), based on the number of layers I can see plus the number of colors.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9GysFr4NPa4/SxdQiwFyv1I/AAAAAAAAALQ/-dRv5Z3QChY/s1600-h/Final+Fantasy+III_00006.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/SxdQiwFyv1I/AAAAAAAAALQ/-dRv5Z3QChY/s400/Final+Fantasy+III_00006.gif" alt="" id="BLOGGER_PHOTO_ID_5410882035263913810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To show off the graphic abilities of the SNES, next is a screen shot of the special effects from casting of a spell, which we're going to dissect.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_9GysFr4NPa4/SxdREtr0QbI/AAAAAAAAAMA/5ugAUBkdHIY/s1600-h/Final+Fantasy+III_00000.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://4.bp.blogspot.com/_9GysFr4NPa4/SxdREtr0QbI/AAAAAAAAAMA/5ugAUBkdHIY/s400/Final+Fantasy+III_00000.gif" alt="" id="BLOGGER_PHOTO_ID_5410882618733642162" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is layer 1. You can see the bubble from the spell here, sporting transparency that tints other layers. Interestingly, you can see part of a screen (the magic selection screen) that isn't open at all; in the composite, this section is covered up by the bottom part of layer 2. In other words, in the top part of the screen layer 1 is drawn on top of all other layers, while the bottom part is drawn at the bottom of the layers; this goes to illustrate what I said about very complicated and flexible interaction between the layers (it's possible this involves changing the layer parameters in between lines, a technique I mentioned being possible on the NES).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_9GysFr4NPa4/SxdRADLQplI/AAAAAAAAAL4/eUVzdWPlAF8/s1600-h/Final+Fantasy+III_00001.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://2.bp.blogspot.com/_9GysFr4NPa4/SxdRADLQplI/AAAAAAAAAL4/eUVzdWPlAF8/s400/Final+Fantasy+III_00001.gif" alt="" id="BLOGGER_PHOTO_ID_5410882538603325010" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Layer 2 is the background for the whole screen, the top section the battlefield, the bottom section the menu system. Note that a sine wave offset pattern has been applied to the battlefield background; while I haven't investigated it to be certain, I suspect this is accomplished by simply modifying the screen scroll position in between drawing each line.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_9GysFr4NPa4/SxdRQnaIqaI/AAAAAAAAAMI/Ry7ArVIfGGI/s1600-h/Final+Fantasy+III_00002.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://4.bp.blogspot.com/_9GysFr4NPa4/SxdRQnaIqaI/AAAAAAAAAMI/Ry7ArVIfGGI/s400/Final+Fantasy+III_00002.gif" alt="" id="BLOGGER_PHOTO_ID_5410882823207299490" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Layer 3, again serving an array of purposes, is used for special effects and the text on the menus. You can't see it clearly at all from just this layer, but this layer is used to produce those discolored blotches on the spell bubble. This may be another case of transparency for the special effect, but it's hard to tell from screen shots alone.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_9GysFr4NPa4/SxdQxYnjyQI/AAAAAAAAALo/lR7cU8IBWFM/s1600-h/Final+Fantasy+III_00003.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://2.bp.blogspot.com/_9GysFr4NPa4/SxdQxYnjyQI/AAAAAAAAALo/lR7cU8IBWFM/s400/Final+Fantasy+III_00003.gif" alt="" id="BLOGGER_PHOTO_ID_5410882286661126402" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To illustrate this fact, layers 1 and 3 together:&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_9GysFr4NPa4/SxdQnjCKnvI/AAAAAAAAALY/KNhn6vWzCK8/s1600-h/Final+Fantasy+III_00005.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://2.bp.blogspot.com/_9GysFr4NPa4/SxdQnjCKnvI/AAAAAAAAALY/KNhn6vWzCK8/s400/Final+Fantasy+III_00005.gif" alt="" id="BLOGGER_PHOTO_ID_5410882117658386162" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And finally, the least interesting part: the sprite layer. Although here again we see something rather unexpected: it looks like there's some type of sprite garbage that is normally (again) covered by the menu.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9GysFr4NPa4/SxdQsXaUE7I/AAAAAAAAALg/XPbn3e4Au2g/s1600-h/Final+Fantasy+III_00004.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/SxdQsXaUE7I/AAAAAAAAALg/XPbn3e4Au2g/s400/Final+Fantasy+III_00004.gif" alt="" id="BLOGGER_PHOTO_ID_5410882200437789618" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;So, that's basically what 7 of the 8 graphics modes are all about. The 8th one, known as &lt;a href="http://en.wikipedia.org/wiki/Mode_7"&gt;Mode 7&lt;/a&gt;, however, is a bit different. It has only a single large 256-color background layer, but it has the ability to apply a transformation matrix to the background, allowing scaling and rotation. This is used very commonly in SNES games, especially with the swap-the-registers-between-lines trick, allowing it to do primitive 3D perspective projection. Believe it or not, that minimap is actually a sprite (as is some of the glow in the background).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9GysFr4NPa4/SxdQb8oWjYI/AAAAAAAAALI/aqRjTqYW8Aw/s1600-h/Final+Fantasy+III_00007.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/SxdQb8oWjYI/AAAAAAAAALI/aqRjTqYW8Aw/s400/Final+Fantasy+III_00007.gif" alt="" id="BLOGGER_PHOTO_ID_5410881918371007874" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;One particularly interesting (in the sense of peculiar) feature of the SNES design is the &lt;a href="http://en.wikipedia.org/wiki/Nintendo_S-SMP"&gt;sound system&lt;/a&gt;. As opposed to most sound systems, the SNES system does not consist of the CPU simply writing channel parameters such as sample #, frequency, etc. to the sound chip which then performs the requested operation. Rather, the SNES has a separate CPU (the SPU) which acts as a sound coprocessor: sound programs are written, assembled, and then executed on this coprocessor; once the program has been uploaded, the sound system can play (e.g. music) without any further involvement of the main CPU at all (I proved this a decade ago by showing that shorting between two pins on the SNES would crash the main CPU while the SPU continued to play the music without missing a beat), though obviously the main CPU must instruct the SPU when it's time to play dynamic sound effects.&lt;br /&gt;&lt;br /&gt;We can only guess why the SNES was designed this way. The most obvious possibility is that this frees the main CPU from having to deal with music and sounds effects, leaving it more cycles to spend on something else (especially in the case where one or more channels of the music must be temporarily dropped to allow a sound effect to be played).&lt;br /&gt;&lt;br /&gt;An alternate possibility that I haven't been able to confirm is that this is done to increase the resolution of the audio system. In Blaster Master, the game would perform all the calculations for the frame, then spin waiting for the vertical blank interrupt to begin work on the next frame. Thus code executed 60 times a second, apparently including audio code. If this is true in the general case, that limits the resolution of audio operations to 1/60 second as well. In contrast, the SPU runs at 1 MHz independent of the main CPU, allowing it to issue commands to the sound generator at any time, in theory allowing for higher music tempo and more complex audial effects.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-7379613110072709061?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/7379613110072709061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=7379613110072709061' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7379613110072709061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7379613110072709061'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/12/almost-as-old-things.html' title='&amp; Almost as Old Things'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_9GysFr4NPa4/SxdQiwFyv1I/AAAAAAAAALQ/-dRv5Z3QChY/s72-c/Final+Fantasy+III_00006.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-945164140473692766</id><published>2009-09-19T21:50:00.000-07:00</published><updated>2009-09-19T21:50:38.072-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>The Taxonomy of Linking</title><content type='html'>There are generally at least two steps to building a program, regardless of language. Compiling takes a source code file (operating on one file at a time), parses it, and produces machine code (or some manner of other thing such as &lt;a href="http://en.wikipedia.org/wiki/Java_bytecode"&gt;Java bytecode&lt;/a&gt;) in what's called an object file. Here, there's one object file produced from each source file.&lt;br /&gt;&lt;br /&gt;Linking then occurs on the set of object files for a project, producing a single binary. 'Linking' refers to connecting the code between object files, so that functions in one file may access functions and data in other object files, which the compiler couldn't do because it works on one file at a time. The linker also adds the operating system-specific wrapper material needed to allow the OS to load and execute the binary.&lt;br /&gt;&lt;br /&gt;That's the general idea, anyway. As with most things, reality is more complicated.&lt;br /&gt;&lt;br /&gt;What was just described is known as static linking (or build-time linking). Static linking is when called code is included directly in the binary. It's loaded and unloaded with all the other code in that binary, and as such is always available. The code may either come from object files, as above, or from what are called static libraries - essentially archives containing multiple object files combined into one.&lt;br /&gt;&lt;br /&gt;However, there are disadvantages to static linking. Because the code is tightly integrated into the binary, it's effectively impossible to update any functions without recompiling the entire binary. Furthermore, because the code is included in each binary, functions used by many binaries must be duplicated, wasting space.&lt;br /&gt;&lt;br /&gt;The alternative to static linking is dynamic linking. In dynamic linking, common functions are built into stand-alone binaries called dynamic link libraries (DLLs). Functions in these DLLs, unlike in static libraries, are not integrated into other binaries by the linker, but instead are called directly from the other binaries. This requires the functions be exported - a process in which the linker writes information into the DLL about what functions the DLL contains and where those functions exist in the DLL; this data is then used by the operating system to allow other binaries to locate and call these exported functions (importing). As DLLs exist independently of binaries that call exported functions, only a single copy of exported functions need exist on disk or in memory, and DLLs may be updated independently of other binaries.&lt;br /&gt;&lt;br /&gt;Dynamic linking may further be classified as load-time linking or run-time linking. In load-time linking the linker, when creating a binary that calls functions in DLLs, creates an import table, which lists all DLLs and functions therein that the binary requires. The operating system then, when loading the binary, automatically loads all of these DLLs and finds the addresses of all imported functions, writing the addresses to fixed places in the binary; the binary may then trivially call the functions through these pointers that are at known locations. This is entirely automatic; the DLLs are automatically loaded when the calling binary is, and unloaded when the calling binary is unloaded (assuming no other binaries still need them), ensuring they're always available when needed.&lt;br /&gt;&lt;br /&gt;To accomplish this, the linker needs what are known as import libraries. These are generated by the linker when it builds the DLL, and contains a list of all functions exported by the DLL. The reason this is necessary is that DLLs themselves contain only a function name (or ordinal number) - only enough information to allow the operating system to locate the desired function; they may not include information such as what parameters a function takes or the calling convention to use to call the function, which are necessary to seamlessly link to the function. A consequence of this is that both the DLL name and all functions needed must be known when the calling binary is linked.&lt;br /&gt;&lt;br /&gt;The other type of dynamic linking is run-time linking. Unlike load-time linking, in which the entire importing process is automatic, the run-time linking process is entirely manual. You must manually load the DLL when you need it, call OS functions to get pointers to the desired functions (which you must manually specify by name/ordinal), manually call the functions through the obtained pointers, making sure you use the right parameters and calling convention, and finally manually unloading the DLL when you no longer need it.&lt;br /&gt;&lt;br /&gt;As this is much, much less convenient, you generally use load-time linking whenever possible, reserving run-time linking only for those times when you can't use load-time linking for one reason or another. Generally this is because you don't know the name of the DLL (or the function to import) at link-time. There may be multiple DLLs with different versions of a function (e.g. in Diablo II there are DLLs for the graphics system, with separate DLLs for DirectDraw, Direct3D, and Glide); the DLL may be loaded based on user action (e.g. loading plugins); the DLL may not exist until run-time (e.g. the calling binary must download the DLL first); etc.&lt;br /&gt;&lt;br /&gt;(for more general information on DLLs, see &lt;a href="http://blogs.msdn.com/oldnewthing/archive/2006/07/27/680250.aspx"&gt;The Old New Thing&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Sometimes, however, you get in the unenviable position of not being able to use either. This is the situation I found myself in when linking &lt;a href="http://sourceforge.net/projects/thundergraft/"&gt;ThunderGraft&lt;/a&gt; to the &lt;a href="http://www.fmod.org/index.php/products/fmodex"&gt;FMOD Ex&lt;/a&gt; DLL. Because the DLL will be packed into a Self-Executing MPQ and extract as a temporary file with a random name, I couldn't use load-time linking (which requires a fixed DLL file name). However, the fact that the DLL was exporting full classes meant that I couldn't use run-time linking either, as the names were too complex to manually specify (with such memorable names as "?createSound@System@FMOD@@QAG?AW4FMOD_RESULT @@PBDIPAUFMOD_CREATESOUNDEXINFO@@PAPAVSound@2@@Z" [spaces inserted so the blog formatting doesn't get all screwed up by the huge string]). Static linking was also out, as the authors do not make a static library of FMOD available (which isn't too surprising as static libraries tend to be compiler- and version-specific).&lt;br /&gt;&lt;br /&gt;Fortunately, there's one more option: delay-loading. Delay-loading is essentially a neat linker trick. It uses an import library for a DLL, but instead of generating import tables it generates code that loads the DLL and get the imported function addresses through the run-time linking functions; the DLL is loaded and the function addresses obtained when an imported function is first called (or you tell the linker code to do so at a time of your choosing). This allows the convenience of load-time linking with the flexibility of run-time linking, and allows you to get out of sticky situations like this one.&lt;br /&gt;&lt;br /&gt;Of course, in this case it was all due to poor design in FMOD to begin with. It's a well-known principle that you should never export full classes; a much better way is to export pure virtual classes. This avoids the problem because functions in virtual classes are not exported individually, but rather accessed through the v-table; no exports to link to, no names to mangle, etc. It's to avoid this very problem that &lt;a href="http://en.wikipedia.org/wiki/Component_Object_Model"&gt;COM&lt;/a&gt; chose to use pure virtual classes as the basis of the COM object system, after all, and there really isn't any better alternative.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-945164140473692766?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/945164140473692766/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=945164140473692766' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/945164140473692766'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/945164140473692766'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/09/taxonomy-of-linking.html' title='The Taxonomy of Linking'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6098505731774532322</id><published>2009-09-15T16:38:00.000-07:00</published><updated>2009-09-15T16:40:48.946-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>&amp; Hobbit Birthday Parties</title><content type='html'>There probably aren't many that care that wouldn't see my &lt;a href="http://www.campaigncreations.org/forum/index.php?topic=1997.0"&gt;post&lt;/a&gt; on Campaign Creations, but here it is just in case:&lt;br /&gt;&lt;span&gt;&lt;/span&gt;&lt;blockquote&gt;&lt;span&gt;Well, it's that time of year again, and I've got some presents to give out. First, I released &lt;a href="https://sourceforge.net/projects/mpqdraft/files/MPQDraft%20Binaries/2009.09.13/MPQDraft20090913.zip/download" target="_blank"&gt;build 2009.09.13&lt;/a&gt; of MPQDraft a couple days ago. While it only fixes bugs, it fixes some major ones - so major I'm amazed nobody told me about them in the last year and I had to find them myself.&lt;br /&gt;&lt;br /&gt;The bugs fixed, in approximate order of severity:&lt;br /&gt;-SEMPQs not activating for games specified with relative names&lt;br /&gt;-plugin page not setting the plugin pointer after selecting with Browse, resulting in a crash&lt;br /&gt;-plugin page stops listing plugins after one fails to load&lt;br /&gt;-not saving custom executable names in the SEMPQ wizard&lt;br /&gt;-plugins weren't forced to use proper plugin IDs for their modules, allowing some plugins to get away with bad behavior that didn't work with FireGraft (which forced plugins to use the correct ID)&lt;br /&gt;&lt;br /&gt;As with the last year and a half, MPQDraft is open-source &lt;a href="http://sourceforge.net/projects/mpqdraft/" target="_blank"&gt;on SourceForge&lt;/a&gt;. You can get both the binaries and the source from the &lt;a href="https://sourceforge.net/projects/mpqdraft/files/" target="_blank"&gt;files page&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Second, &lt;a href="https://sourceforge.net/projects/thundergraft/files/ThunderGraft%20Binaries/ThunderGraft20090915.zip/download" target="_blank"&gt;ThunderGraft&lt;/a&gt; has been resurrected &lt;a href="http://qstuff.blogspot.com/2009/08/story-of-thundergraft.html" target="_blank"&gt;from the dead&lt;/a&gt;. For those who haven't heard about ThunderGraft before, it allows the use of MP3s, Ogg Vorbis, and other sound compression formats in Diablo, Diablo II, StarCraft, and WarCraft II: Battle.net Edition, which give higher audio quality and smaller file sizes than the WAV compression used in those games normally; ThunderGraft also integrates with StarEdit to allow maps to use non-WAV sounds in triggers. I'm calling it a beta version as ShadowFlare just yesterday mentioned a crash that only occurred on her computer, and I probably won't have time to investigate it until at least tomorrow.&lt;br /&gt;&lt;br /&gt;And finally, as sort of "present #2.5", ThunderGraft has been open-sourced as well, and it's also &lt;a href="http://sourceforge.net/projects/thundergraft" target="_blank"&gt;on SourceForge&lt;/a&gt;. The binaries are available on the &lt;a href="https://sourceforge.net/projects/thundergraft/files/" target="_blank"&gt;files page&lt;/a&gt;, but I haven't gotten around to putting a ZIP of the source up yet. Specifically, I really, really need to clean up the directory structure of MPQDraft and ThunderGraft to make it much easier for people other than me (without my directory organization) to compile it. You can still view the source through the &lt;a href="http://thundergraft.svn.sourceforge.net/viewvc/thundergraft/" target="_blank"&gt;source browser&lt;/a&gt;, or download it with &lt;a href="https://sourceforge.net/projects/thundergraft/develop" target="_blank"&gt;Subversion or CVS&lt;/a&gt;, but you probably won't get it compiled without a bit more info from me; I'll get to that when I have time.&lt;br /&gt;&lt;br /&gt;As always, there are two flavors: release and debug. I'd advise using debug for mod development, as it generates log files that are very helpful in fixing bugs, should you find any (but would probably annoy people who download your mod).&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;/span&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6098505731774532322?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6098505731774532322/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6098505731774532322' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6098505731774532322'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6098505731774532322'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/09/hobbit-birthday-parties.html' title='&amp; Hobbit Birthday Parties'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-3799049072403219307</id><published>2009-08-31T08:00:00.000-07:00</published><updated>2009-08-31T11:15:49.225-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>&amp; Very Old Things - Part 3</title><content type='html'>So. Thus far everything I did involved nothing more than the memory editor and cheat search. In other words, something just about anybody could do. To really say that I reverse-engineered Blaster Master, I needed something a lot bigger, and I knew just what to do: I was gonna find the cause of a 21-year-old bug. There's a well known glitch in Blaster Master that on some bosses, if you or the boss is being hit when you pause the game, you (or the boss) will continue to take damage while the game is paused. This only works on some bosses, however, leaving a big question mark as to whether it's a bug or a feature (it was especially strange that it affected both player and boss); I wanted to find out.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_9GysFr4NPa4/Sph0l0bSwdI/AAAAAAAAAKw/E75KeUl8qCs/s1600-h/6502Debugger.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 230px;" src="http://4.bp.blogspot.com/_9GysFr4NPa4/Sph0l0bSwdI/AAAAAAAAAKw/E75KeUl8qCs/s400/6502Debugger.gif" alt="" id="BLOGGER_PHOTO_ID_5375174348343787986" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Unsurprisingly, it's quite a bit of work to reverse-engineer something you have absolutely no info on (e.g. in computer programs you at least know OS API calls the program makes, and can use that as a starting point), especially when you're learning both the hardware and the assembly language as you go. Ultimately, it took me an embarrassingly long time to get the job done (certainly more than it was worth), and I ended up disassembling a lot more of the game than was necessary (as is often the case when you don't have any idea what you are looking for). I'll just talk about some of the more important lines of investigation, findings, and complications.&lt;br /&gt;&lt;br /&gt;As I didn't know anything about the game, naturally the first thing was to hit "step into" and see where I ended up. I always ended up in the same place: a busy loop that checks a single value. Given the nature of this and some idea about the hardware, I reasoned that this was a loop to wait for the next vertical sync, to start on the next frame; this was confirmed by observing that address being written to from the non-maskable interrupt (vsync) handler.&lt;br /&gt;&lt;br /&gt;From there I stepped out of the function and took a look around, writing down the various functions called after vsync. I then went about refining the list and detailing more levels of the call tree, ultimately (after all of my disassembly) resulting in the call tree and other related notes below (note the comments have a focus on things relevant to finding this pause glitch). One thing of particular importance is that there's an object-oriented handler for each object type, and the appropriate handler is called for each non-empty object table entry.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$E936 waits for vertical blank to occur&lt;br /&gt;$C971: for each object calls $C8DF, decreases hit timer if nonzero, calls $C9A4, and calls $C928&lt;br /&gt;-$C8DF copies object data from $400+$56 to $46 ($C925 writes life)&lt;br /&gt;-$C9A4 sets hit timer back to full and decreases life in the object buffer when hit with hit timer at 0 after decrement&lt;br /&gt;--$EA3A&lt;br /&gt;--$EB51 saves the object-specific handler to $7A (LE)&lt;br /&gt;--jumps to the object-specific handler at $C9D3&lt;br /&gt;-$C928 copies object data from $46 to $400+$56&lt;br /&gt;$CA4B-&gt;$EA3A-&gt;$E61B-&gt;$E63C/$EB98 unmaps $8DF6 page [the page the object handlers are], which gets mapped by the NMI handler&lt;br /&gt;&lt;br /&gt;$EB7E NMI handler (does not branch)&lt;br /&gt;$EB97 IRQ/BRK handler (stub)&lt;br /&gt;$F7: controller 1 state (bits in reverse order)&lt;br /&gt;$F8: controller 2 state (bits in reverse order)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;For a while I did some looking around with breakpoints on the location in the object buffer where the life is stored, looking for things that modify it. Some of the information gathered this way:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Copy of object struct for current object: 46&lt;br /&gt;Buffer used to hold 16-bit pointers [LE] from various tables: 7A&lt;br /&gt;&lt;br /&gt;$53 [life of the current object] written to directly by $8DF6 in $C9A4 when damage is taken&lt;br /&gt;$8C6B-8C9F, $8DDF-8DFE (inside $8D76) only executed when hit timer is 0&lt;br /&gt;During pause taking hit, $C1E6-&gt;$D7A0 returns A0/N+ to $8DD5 on boss 2, but 7F/N- to boss 5&lt;br /&gt;&lt;br /&gt;$D7A0 seems to determine whether you get hit during pause. $7E indicates whether you're being hit or not: high bit for hit, lower bits for damage taken.&lt;br /&gt;$7E is written to by $D71A in ($C141-&gt;$D711) when hit by boss, $D7B2 to clear hit per frame. $D71A is not reached when paused with boss 5 because $D6CD does not return&lt;br /&gt;$D6CD returns if the current object is hitting the player, throws an "exception" returning to caller of caller if not hitting (returns from $D710)&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Eventually I decided to take a more systematic look at the object handler for the catacombs (overhead view) player object:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$8C38-&gt;8D98-&gt;$8DBF catacombs player object handler paused&lt;br /&gt;-$C15F&lt;br /&gt;-$C0FF-&gt;$EF2B sets $3E and $3F to the X and Y coordinates (in pixels on screen) of the player for $D7A0&lt;br /&gt;-$C1E6-&gt;$D7A0 returns A0/N+ to $8DD5 on boss 2, but 7F/N- to boss 5, when paused and being hit. A indicates the damage player should take. highest bit of A and the negative flag indicates whether player is hit or not.&lt;br /&gt;-on N+, $C216 then handles hit (including decrease life)&lt;br /&gt;-$93BD&lt;br /&gt;-$EA3A&lt;br /&gt;-$F029&lt;br /&gt;-$E63C&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;From this we can see that $C1E6 is the switch we're looking for, determining whether the player takes damage; though a look through the function shows a clear lack of anything resembling hit detection - it simply reads from a struct in memory at $7C, generated who knows where. So, if that isn't determined in the player object handler, maybe it was handled in the objects you can be hit by. For that reason, and to satisfy my curiosity a bit about what makes bosses tick, I decided to take a look at a boss handler function; and as I hate the crab boss so much, naturally I went with that, first.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9GysFr4NPa4/So3Xd36oazI/AAAAAAAAAKI/4r9fYXcNzLQ/s1600-h/HardShellFight.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/So3Xd36oazI/AAAAAAAAAKI/4r9fYXcNzLQ/s400/HardShellFight.gif" alt="" id="BLOGGER_PHOTO_ID_5372186838748916530" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;It was about this time that I discovered that NOPing function calls was a very effective way to quickly get an idea what a function is doing. This method works poorly on computers, because of the greater number of registers and drastically greater stack usage, making such NOPs result in crashes more often than not. On the NES (or at least in Blaster Master), however, the method works very well, with crashes very uncommon.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;Crab (level 5) boss unpaused object handler ($A6D0):&lt;br /&gt;-$A07B: (no discernible effect)&lt;br /&gt;-$A6DE: handles movement of crab and state transitioning (but not animation)&lt;br /&gt;-$A7A2: spawns bubbles when necessary&lt;br /&gt;--$C1F5: spawns a bubble&lt;br /&gt;-$C0FF: updates crab screen position based on crab 65 position (NOPout fixes crab position where it shouldn't be, despite crab 65 object movement). affects everything onward.&lt;br /&gt;-$C153-&gt;$EB51&lt;br /&gt;-for each body segment (right pincer, left pincer, back):&lt;br /&gt;--$C141-&gt;$D711: detection of whether player has been hit. detection of player being hit by green sprite is elsewhere.&lt;br /&gt;---$D6CD: checks for collision&lt;br /&gt;--$C216-&gt;$DECC (only if hit)&lt;br /&gt;-$C12C: (no discernible effect)&lt;br /&gt;-$C189: draws (animates?) the green sprite&lt;br /&gt;-$C144-&gt;$D697: sets player damage if player hits green sprite. also handles things damaging the boss.&lt;br /&gt;--$D6CD: returns on collision (either player hit by something or boss hit by something). eats the stack frame if no collision (returns to caller of caller)&lt;br /&gt;-$9EB3: animates the background layer&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Okay, so $D6CD is another function that looks like a good candidate. So, let's take a look and see if it's what we're looking for or another tangentially related function (don't blame me for the formatting, Blogger doesn't like indentations).&lt;br /&gt;&lt;br /&gt;&lt;code&gt;$44 = A&lt;br /&gt;$00 = $3E - ($40 / 2)&lt;br /&gt;$01 = $3F - ($41 / 2)&lt;br /&gt;X = 0xF&lt;br /&gt;do&lt;br /&gt;{&lt;br /&gt;A = $7E[X]&lt;br /&gt;if (A &gt; 0)&lt;br /&gt;{&lt;br /&gt;$45 = A&lt;br /&gt;A = $7C[X] - $00&lt;br /&gt;if (A &amp;lt;= $40)&lt;br /&gt;{&lt;br /&gt;A = $7D[X] - $01&lt;br /&gt;if (A &amp;lt;= $41)&lt;br /&gt;return&lt;br /&gt;}&lt;br /&gt;}&lt;br /&gt;X -= 3&lt;br /&gt;} while (X &amp;gt;= 0)&lt;br /&gt;&lt;br /&gt;throw&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;Now that looks like a collision detection function, more or less. We can see the X coordinate, Y coordinate, width, and height of whatever it is we're comparing against at $3E-$41, respectively (this is a case of a memory region being used like a stack frame). We can also see an array of 5 structs containing the X coordinate, Y coordinate, and a thingy, respectively, starting at $7C. Clearly only the size of the "current" object is considered, and the array of thingies are just points.&lt;br /&gt;&lt;br /&gt;Well, let's think about it for a minute. We know that this function is called 4 times for the crab boss, for the 4 different parts of the body (and that one of those is not like the others). What might collide with the boss that would be of interest? Well, the player and the player's projectiles. A bit of playing around proved this to be true: the first entry in the array is the player, the rest are the player's projectiles (limited to 4, as you can see). That third byte in the struct array indicates the amount of damage the projectile does (or 7F for the player).&lt;br /&gt;&lt;br /&gt;So, now we have everything we need to figure out how this works. The boss object checks for collisions with the player and the player's projectiles. If it hits the former, it marks the player for damage, which is then applied by the player object handler (presumably next frame, since the player handler always gets executed before enemy handlers); if it's the latter, the boss takes damage, though only if the part hit is the green sprite, which is the hit box.&lt;br /&gt;&lt;br /&gt;Now that we know how the collision detection and damage system works, and why bosses that are susceptible to being hit while paused also themselves can hit you while paused (the collision detection for both is one in the same); that just leaves the question of why it only operates on some bosses. Well, it was about here that I discovered that that wasn't actually true. While only some bosses can be hit (and hit you) while paused, this is not the case for projectiles. Specifically, the projectiles fired by boss 3 and boss 8-1 can hit you while paused, even though the boss cannot be hit while paused.&lt;br /&gt;&lt;br /&gt;Well, it turns out there are two sets of object-specific handlers, one for when the game is running, one for when it's paused. Now, bullets and other things are generally not prone to the problem of dealing damage while paused, as they disappear as soon as they hit something (e.g. the bubbles spewed by the crab boss). The things that can hit you while paused appear to be exactly those objects that have pause handlers and that don't disappear after hitting you; this is the case with all susceptible bosses, plus the projectiles of bosses 3 and 8-1.&lt;br /&gt;&lt;code&gt;Boss object handlers:&lt;br /&gt;1 (63): base $A58A, paused stub&lt;br /&gt;2 (5F): $9B64&lt;br /&gt;3 (61): $A196, paused stub&lt;br /&gt;4 (5D): $970C&lt;br /&gt;5 (65): $A6CD, paused stub&lt;br /&gt;6 (5F): $9B64&lt;br /&gt;7 (5D): $970C&lt;br /&gt;8-1 (67): $AA34, paused stub&lt;br /&gt;8-2 (69): $AC84, paused stub&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;While I didn't go searching for every single object handler to compare the paused and non-paused versions, I did compile a list of the ones for the bosses. Note that there is only actually a single table of handlers in memory; the address in the table points to the paused handler, while the unpaused handler is always 3 bytes afterward (3 bytes is the size of a JMP instruction). For the bosses not prone to this glitch, you can see that I've indicated the pause handler is a stub that returns immediately. For the rest, the pause handler jumps midway into the unpaused handler (after things like movement).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9GysFr4NPa4/Sph2JkzGuqI/AAAAAAAAAK4/FeXjNRA6p9A/s1600-h/BlasterMasterBoss2.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/Sph2JkzGuqI/AAAAAAAAAK4/FeXjNRA6p9A/s400/BlasterMasterBoss2.gif" alt="" id="BLOGGER_PHOTO_ID_5375176062135614114" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;To illustrate this, take a look at the handler for boss 2 ($9B67):&lt;br /&gt;&lt;code&gt;-$A07B: (no discernible effect)&lt;br /&gt;-$C01E: handles movement of boss&lt;br /&gt;-if time to spawn next projectile:&lt;br /&gt;--$C1F5-&gt;$D851: fork projectile from boss, giving it a new proto-object type&lt;br /&gt;--$C216&lt;br /&gt;-paused handler jumps directly to here&lt;br /&gt;-$C0FF&lt;br /&gt;-$9D77: draw and do hit detection for arms&lt;br /&gt;-$C090-&gt;$D770: do hit detection for back (not hit box)&lt;br /&gt;--$D711: hit detection&lt;br /&gt;-$C093: do hit detection for hit box&lt;br /&gt;-$9EB3: moves and animates the background&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;So, that's how it is. Now we know why it happens and why it only affects some things. That just leaves one more question: is it a bug or a feature? Unfortunately, the evidence is much too ambiguous to answer that clearly. While it's within the bounds of imagination that damaging the boss during pause could have been intentionally put in as a cheat of sorts, it's very hard to imagine that the same thing against the player would be intended.&lt;br /&gt;&lt;br /&gt;Yet it's also hard to imagine that it could be a bug; while the player being hit during pause could be eliminated by a single change to the player handler (a single mistake, in other words), doing the same for bosses would require that every boss's handler be changed. Furthermore, there's the fact that only 2 of the 5 unique boss object handlers (2 of them are used for 2 bosses each, bringing the total to 9 bosses) have pause handlers, in contrast to the player and most projectiles, and without pause handlers the bosses don't even get drawn completely (and what point is there in having a pause that lets you see the boss battle if you can't see the boss?). It seems as though a lot of stuff was left out or in arbitrarily; I have to wonder if there is a deadline lurking in here, somewhere.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_9GysFr4NPa4/SpiLHxd_gfI/AAAAAAAAALA/QfqitJ-T09M/s1600-h/BlasterMasterEnd.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://1.bp.blogspot.com/_9GysFr4NPa4/SpiLHxd_gfI/AAAAAAAAALA/QfqitJ-T09M/s400/BlasterMasterEnd.gif" alt="" id="BLOGGER_PHOTO_ID_5375199120921166322" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Various resources used during reverse-engineering:&lt;br /&gt;&lt;a href="http://nesdev.parodius.com/ndox200.zip"&gt;Nintendo Entertainment System Documentation&lt;/a&gt;&lt;br /&gt;&lt;a href="http://nesdev.parodius.com/6502jsm.zip"&gt;6502 Instruction Summary&lt;/a&gt;&lt;br /&gt;&lt;a href="http://nesdev.parodius.com/nesgfx.txt"&gt;How NES Graphics Work&lt;/a&gt;&lt;br /&gt;&lt;a href="http://nesdev.parodius.com/mappers.zip"&gt;Comprehensive NES Mapper Document&lt;/a&gt;&lt;br /&gt;For more info, see this &lt;a href="http://nesdev.parodius.com/"&gt;big list&lt;/a&gt; of documents&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-3799049072403219307?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/3799049072403219307/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=3799049072403219307' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3799049072403219307'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3799049072403219307'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/08/very-old-things-part-3.html' title='&amp; Very Old Things - Part 3'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_9GysFr4NPa4/Sph0l0bSwdI/AAAAAAAAAKw/E75KeUl8qCs/s72-c/6502Debugger.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-921321592635796265</id><published>2009-08-29T14:18:00.000-07:00</published><updated>2009-08-29T14:18:00.628-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='hacking'/><title type='text'>&amp; Very Old Things - Part 2</title><content type='html'>As for the hacking itself, this started out with simple stuff. Search memory, find special values (life, lives, gun power, boss items, etc.), and overwrite them. This was quite easy with an emulator that has a cheat search feature; you simply have it save the memory contents at the initial state, the repeatedly perform searches based on specified criteria until you've narrowed it down to 1 or a small number of possibilities. For example, finding player health was a trivial matter of searching for something that decreases each time you take damage and stays the same in between damage.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9GysFr4NPa4/SphxwaWj7lI/AAAAAAAAAKo/pwH9vHTYptA/s1600-h/BlasterMasterPaused.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/SphxwaWj7lI/AAAAAAAAAKo/pwH9vHTYptA/s400/BlasterMasterPaused.gif" alt="" id="BLOGGER_PHOTO_ID_5375171231788297810" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;With the exception of the boss items, all of the others in this list were similarly easy to find. Boss items, however, were a bit more complicated. Because you only get the items after beating a boss, naturally this is a situation where there are likely to be a lot of changes all over RAM, as it's a major transition in the gameplay; this means that you can't narrow it down as easily. I had to try several locations, starting with the ones whose values made them the most probable to be correct (specifically ones that had a bit flipped on when the item was picked up).&lt;br /&gt;&lt;br /&gt;However, there was one other complication figuring that one out: boss items are represented by two separate bit masks that are partially redundant. I first discovered the mask at 3FC, because that's the one that changes the bullet your tank fires after you get the first boss item; as it was a visual change, it was very easy to see that it was working. Once I found that, I checked to see if it was a bit flag, and confirmed it was, finding the flags for the second and third boss items by experimentation.&lt;br /&gt;&lt;br /&gt;That's where things got weird. While this mask contained flags for boss items, the flags for the other boss items didn't seem to actually do anything. As well, while having the hover bit flag set caused hover power to be displayed (it's hidden prior to getting the third boss item), you couldn't actual hover. The bits here also did not make the upgrades show up on the pause screen. So, I went on, with my infinite life and gun power, and killed a few more bosses (somehow I still remember most of the maps of this game).&lt;br /&gt;&lt;br /&gt;I found that there was a second bit mask with a completely different set of flags, one for each of the 7 items in the game. For the first 2 items, these flags did nothing more than make the item show up in the pause screen. For the third item (hover) this flag allowed you to hover, but did not show the hover power bar or allow you to accumulate hover power (so you still couldn't actually fly with this flag alone). I still can't imagine why it was done this way, but at least I figured out all the flags.&lt;br /&gt;&lt;br /&gt;One thing that I couldn't figure out with cheat searches, however, was boss life. That is, I found it - repeatedly: it was in a different place every time (including even for the same boss). I correctly reasoned that this implied that the boss's life was not a special value, but that bosses were simply common entries in the list of objects in the game. As it turns out, so is the player; you just don't notice that because the player is always at index 0 in the object array and thus always at address 0x400, while the boss was stuck in whatever slot was available at the time. This led directly to the discovery of the object array itself. From there, I started looking at the struct that represented each object, beginning with offset 0xD: life.&lt;br /&gt;&lt;br /&gt;As I've already pointed out that you tend to have to get clever when coding on a system with so little RAM, it shouldn't be surprising that maps are stored in a similarly clever way. As far as I can tell, there is only a single map for each area in the game (8 areas), which is 128x256 or less. However, the map is diced up and jam-packed in there such that they need to do some camera tricks when transitioning between areas (teleporting through some doors) to make sure you never see other sections that are contiguous in memory.&lt;br /&gt;&lt;br /&gt;While I was working on it, I figured I should try to answer some long-standing questions about Blaster Master. To begin with, why does the power of your gun (what it actually shoots) not always match the gun power that's displayed? For example, if you have full gun (8 bars) and get hit, you take 1 bar of damage, but the effect of your gun falls beneath what 7 bars should give you. Many years ago I hypothesized that there were two variables for gun power; one was the one displayed, and one that was the actual effect: getting hit did a bit more damage to effect than the display.&lt;br /&gt;&lt;br /&gt;It turned out to be simpler than that. It's a consequence of the fact that while most hits (I can't think of any counterexamples) do an integral number of bars of damage, life, gun, and hover are stored from 0-FF, in bytes. See where this is going? One bar = 20, but 8 bars = FF, not 100. In other words, the number of bars displayed is (x + 1) / 20. When you get full gun and then take a hit, your gun drops to DF; while this still displays as 7 bars, it doesn't give you the maximum gun effect (which requires E0). It's not clear whether this is a bug or a feature, though I'm kind of leaning toward a bug (specifically, an edge case the coders didn't think of, which could be easily solved).&lt;br /&gt;&lt;br /&gt;All numbers are in hex.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;code&gt;Continues: 37E&lt;br /&gt;Lives: DD&lt;br /&gt;Gun: C3&lt;br /&gt;Hover: 92&lt;br /&gt;Bosses killed: 3FB. bit x = boss x+1&lt;br /&gt;Boss items 1: 3FC. same values as 3FB.&lt;br /&gt;Boss items 2: 99. bit 0: hover, 1: dive, 2: wall 1, 3: wall 2, 4: crusher, 5: key, 6: hyper&lt;br /&gt;Homing Missiles: 6F0&lt;br /&gt;Lightning: 6F1&lt;br /&gt;Thunderhead Missiles: 6F2&lt;br /&gt;Pause: 15&lt;br /&gt;&lt;br /&gt;Gun Levels:&lt;br /&gt;20: 2 long shots&lt;br /&gt;40: 3 long shots&lt;br /&gt;80: circling shots&lt;br /&gt;C0: white wave shots&lt;br /&gt;E0: full wave shots&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Beginning of Object Table: 400. 12 slots. Slot 0 is reserved for the player. Slots 1-4 are reserved for projectiles. Enemies fill slots 5-11 as needed.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;code&gt;Object Struct (14 bytes)&lt;br /&gt;byte @0: Object type. A few of the known object types:&lt;br /&gt;3: Normal&lt;br /&gt;4: Dying&lt;br /&gt;5: On left wall&lt;br /&gt;6: On right wall&lt;br /&gt;7: On ceiling&lt;br /&gt;8: Diving&lt;br /&gt;9: Climbing H-&gt;V convex&lt;br /&gt;A: Climbing V-&gt;H convex&lt;br /&gt;B: Climbing horizontal-&gt;vertical concave&lt;br /&gt;C: Climbing V-&gt;H concave&lt;br /&gt;D/E/F 10/11/12: Entering/transitioning/leaving door right/left&lt;br /&gt;1B: Outside tank&lt;br /&gt;1D: Entering tank&lt;br /&gt;84/85/86: Entering/transitioning/leaving door catacombs&lt;br /&gt;&lt;br /&gt;byte @1: Orientation. The exact meaning of this seems to vary by object type.&lt;br /&gt;Tank mode: Between 0 for left and F for right (the intermediates indicate that the tank is changing face), with the high bit set if the tank is pointing to the left&lt;br /&gt;Catacombs mode: 0 for up, 1 for right, 2 for down, etc.&lt;br /&gt;uint16 [LE] @2: Horizontal position. The high byte indicates the attribute-size tile, while the bottom byte is the position within that tile. The highest bit indicates that you're currently moving through a teleporting door.&lt;br /&gt;uint16 [LE] @4: Vertical position&lt;br /&gt;byte @6: X velocity&lt;br /&gt;byte @7: Y velocity&lt;br /&gt;byte @8: Attribute-size tile index on screen? This was always observed to be (Y * 0x11) + X where X and Y are relative to the tiles visible on screen.&lt;br /&gt;byte @9: Hit timer: the number of ticks until the object can be hit again. Controls invulnerability, damage flashing, and also decreases gun by 1 for each tick above 1 (this causes gun power to drop smoothly rather than suddenly, though I'm not sure why they did it this way; life does not do this when damage is taken).&lt;br /&gt;byte @A: Current AI state&lt;br /&gt;byte @B: Frames till AI state change&lt;br /&gt;byte @C: ?? (no observed effect)&lt;br /&gt;byte @D: Life. For trivia value, normal tank shot does 4, hyper shot does 6, crusher shot does 8, normal catacomb shot does 1, catacomb shot with wave gun does 2, and grenades do 2.&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Note that the AI state bytes in the struct are for simple enemies. Bosses have other state stored elsewhere. For example, in the above crab boss, the AI state and timer control movement but not spraying bubbles, which occurs entirely independently. The density of bubble spray, however, was directly controlled by the life of the boss; e.g. below 0x20 life (it starts with 50) it does the full sawtooth volley with dozens of bubbles.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-921321592635796265?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/921321592635796265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=921321592635796265' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/921321592635796265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/921321592635796265'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/08/very-old-things-part-2.html' title='&amp; Very Old Things - Part 2'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_9GysFr4NPa4/SphxwaWj7lI/AAAAAAAAAKo/pwH9vHTYptA/s72-c/BlasterMasterPaused.gif' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-5508930516627930329</id><published>2009-08-26T15:24:00.000-07:00</published><updated>2009-08-26T15:25:05.200-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>The Story of ThunderGraft</title><content type='html'>For those who aren't familiar with it, ThunderGraft was possibly the coolest of the three modding tools I released (the other two being MoPaQ 2000 and MPQDraft). Diablo, Diablo II, Starcraft, and Warcraft II: BNE all use &lt;a href="http://en.wikipedia.org/wiki/Pulse-code_modulation"&gt;PCM&lt;/a&gt; &lt;a href="http://en.wikipedia.org/wiki/WAV"&gt;WAV&lt;/a&gt; audio (22khz 16-bit if I recall correctly) for their sound effects and music. Diablo used raw PCM WAV audio, while Starcraft introduced (and the other two used) a special "WAV compression", which compressed the audio in lossy &lt;a href="http://en.wikipedia.org/wiki/Adaptive_DPCM"&gt;ADPCM&lt;/a&gt; form, resulting in a compression ratio between 3:1 and 4:1 (though at the cost of audio quality); WAV compression, however, was implemented transparently in the MPQ API - the games saw what they read and wrote to the MPQs as simply PCM, and that's all the audio streaming API was capable of playing (in other words, the audio streaming functions were identical in all four games).&lt;br /&gt;&lt;br /&gt;ThunderGraft was a utility that added the ability for all four of these games to play MP3s and Ogg Vorbis, in addition to standard PCM WAVs; even better, it did this in a version-independent way* (the very same ThunderGraft binary worked for all versions of all of those games). Naturally this was huge, especially in the days of dial-up (which was when the modding community first became big). You could use modern audio compression formats that yielded significantly smaller file sizes and higher audio quality compared to WAV compression. Yet ThunderGraft is all but dead now. Why is that?&lt;br /&gt;&lt;br /&gt;MPQDraft and ThunderGraft have a few things in common. They're both very simple, clean, version/program independent, and highly effective. The reason is also the same: they both rely on very clean exploits of design to do their thing, without getting into messy exploits of implementation that depend on the precise binary patched. MPQDraft exploited the priority system in the MPQ API; ThunderGraft exploited the fact that the audio streaming API was encapsulated in functions supplied in Storm.dll.&lt;br /&gt;&lt;br /&gt;The fact that the functions were entirely contained in Storm meant that I could cleanly capture calls to them and redirect them. For cleanliness, I opted to simply replace the streaming API in its entirety. Anything less would have been version-dependent, as it would have required all sorts of messy code modifications inside Storm's internal functions.&lt;br /&gt;&lt;br /&gt;This meant that I needed my own decoding and streaming code to replace Storm's. At the time I just coincidentally happened to have such a thing handy. Specifically, a friend of mine by the moniker Dark_Brood was writing a game engine called Aegis, and happened to have audio decoding/streaming code handy for me to plug into ThunderGraft. He sent me a static library of the code, and in it went. Easy.&lt;br /&gt;&lt;br /&gt;Where things took a turn for the worst was when he wrote the next iteration of his game engine. This involved rewriting a whole bunch of stuff, and integrated the various systems in the engine much more tightly (e.g. added garbage collection and other global things). This meant that it was no longer possible to simply extract the audio portion of the engine.&lt;br /&gt;&lt;br /&gt;While in theory I could have just continued to use the old version, there was a big problem: I never had the code for the original version, nor did he save a copy after rewriting the code. This is a big problem because static libraries are compiler- and version-dependent. Now the only way I could even compile ThunderGraft was on the very same version the original was compiled on: Visual C++ 6, which is some 11 years old, now, and I haven't even had it installed for many years.&lt;br /&gt;&lt;br /&gt;Thus, the only way to resurrect ThunderGraft would be to replace the decoding and streaming system entirely, and thus far I simply haven't managed to muster the effort. After open-sourcing MPQDraft I wanted to do the same with ThunderGraft, but was unable to readily do so for the same reason.&lt;br /&gt;&lt;br /&gt;*There is one thing that's version-dependent in ThunderGraft, as there's simply no theoretical way to do it in a version-independent way: importing of non-WAV audio files into maps with StarEdit (the Starcraft map editor). Special support for this was required for several reasons: 1. StarEdit verifies that things imported are WAVs and refuses anything else, 2. it needed to know how long the audio file was in order for triggers to work right. The audio decoding and streaming in ThunderGraft, in contrast, was truly game- and version-independent.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-5508930516627930329?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/5508930516627930329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=5508930516627930329' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5508930516627930329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/5508930516627930329'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/08/story-of-thundergraft.html' title='The Story of ThunderGraft'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6096333270292980828</id><published>2009-08-23T21:44:00.000-07:00</published><updated>2009-08-23T21:57:50.359-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>&amp; Very Old Things - Part 1</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9GysFr4NPa4/SoybSHd8-eI/AAAAAAAAAKA/h8EpbjxOe6Q/s1600-h/HardShellLarge.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 368px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/SoybSHd8-eI/AAAAAAAAAKA/h8EpbjxOe6Q/s400/HardShellLarge.gif" alt="" id="BLOGGER_PHOTO_ID_5371839191090788834" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;Bring back any painful memories?&lt;br /&gt;&lt;br /&gt;So, a couple days I had one of those evil, perverted urges I'm so notorious for. Specifically, I felt like doing a bit of hacking of &lt;a href="http://en.wikipedia.org/wiki/Blaster_Master"&gt;Blaster Master&lt;/a&gt;. For those not familiar with it, it was an &lt;a href="http://en.wikipedia.org/wiki/Nintendo_Entertainment_System"&gt;NES&lt;/a&gt; game published 21 years ago. A good one, in fact. But before I talk a bit about anything I did resembling reverse-engineering, let me explain the NES hardware to the best of my knowledge (which consists of what I saw in my hacking, and a bit of stuff I looked up online).&lt;br /&gt;&lt;br /&gt;The main CPU of the NES is a modified &lt;a href="http://en.wikipedia.org/wiki/6502"&gt;6502&lt;/a&gt;, the CPU used in various Commodore and Apple computers (not that I ever used one of those). The 6502 is a primitive CISC CPU, and in fact somewhat resembles the x86 (though more primitive). It has 3 8-bit registers: a numeric accumulator (A) and 2 index registers (X and Y). Operations generally operate on the value of A and a memory location or literal, and write the result back to A.&lt;br /&gt;&lt;br /&gt;It has a stack, though from what I saw in Blaster Master it seems to be relatively rarely used, used mainly to save registers (though even that was pretty rare). Specifically, I didn't see much in the way of stack frames holding local variables. Functions that require local variables tended to have (dedicated) memory ranges allocated to them to be used as private buffers. For example, one address I initially thought was the boss life location actually turned out to be in a buffer region used by the function while updating objects in the object list. This kind of surprised me, as the NES has only 2 KB of RAM; I imagine this must be forced by the architecture, e.g. a lack of instructions to access the stack at a specific offset.&lt;br /&gt;&lt;br /&gt;As for the graphics system. If you ever messed around with text mode and text graphics in DOS, the NES graphics system is similar. At the lowest level, graphics are stored as blocks called patterns. Each pattern is 8x8 pixels, 2 bits each (total of 4 colors). The NES has enough video memory for 512 patterns at a time, stored in 2 pattern tables. What exactly it does with these patterns depends. The NES has 3 graphics layers: 1 for background and 2 for sprites (1 in front of and 1 behind the background layer).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://benfry.com/deconstructulator/"&gt;deconstructulator&lt;/a&gt; provides an excellent illustration for most of the things discussed here. It shows the pattern tables (note that the top half is the sprite pattern table and the bottom half is the background pattern table) and sprites along with a playable version of Super Mario Bros.; although it does not show the name/attribute tables. Refer to that from here onward.&lt;br /&gt;&lt;br /&gt;The background layer (illustration below) is very much like the screen buffer in DOS text mode; it's a buffer of screens composed of 32x30 patterns each (indices into the pattern table), called name tables (lost in translation, perhaps?); all patterns in the background must come from the same pattern table. The NES supports up to 4 screen buffers in this way, though it only contains enough memory for 2 of them (if the cartridge doesn't supply additional memory, the game can simply set the NES to mirror the 2 screens).&lt;br /&gt;&lt;br /&gt;However, so far each pixel only has 2 bits of color (the bits in the pattern table). An additional table, called the attribute table, supplies an additional 2 bits to the name tables, increasing the total to 4 bits, or 16 colors (though each tile on screen still has only 4 colors within it). However, the attribute table does not contain a value for every tile. Rather, it only contains 1 two-bit entry for each block of 2x2 entries in the name table (so 16x16 blocks composed of 4 patterns). This is the reason 16x16 blocks appear everywhere in NES games - that's the smallest block that can be fully independently controlled.&lt;br /&gt;&lt;br /&gt;The background position is specified independently of the sprites. A horizontal and vertical scroll position is specified by pixel for the background, which indicates where the graphics chip should start drawing the background on screen. This is how smooth scrolling works, although implementing this can be quite a trick, as you have to essentially use the name tables as a ring buffer (even more tricky if you support scrolling in both dimensions).&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_9GysFr4NPa4/SpIdlzxQ3MI/AAAAAAAAAKg/x-JTF-c2MWA/s1600-h/BlasterMasterLarge.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://4.bp.blogspot.com/_9GysFr4NPa4/SpIdlzxQ3MI/AAAAAAAAAKg/x-JTF-c2MWA/s400/BlasterMasterLarge.gif" alt="" id="BLOGGER_PHOTO_ID_5373389840795622594" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9GysFr4NPa4/SpIWSazBDdI/AAAAAAAAAKQ/AiskVEQE-v0/s1600-h/BlasterMasterBackgroundLarge.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 375px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/SpIWSazBDdI/AAAAAAAAAKQ/AiskVEQE-v0/s400/BlasterMasterBackgroundLarge.gif" alt="" id="BLOGGER_PHOTO_ID_5373381811093179858" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;A shot of the side-scrolling portion of Blaster Master (top) and the corresponding, merged name/attribute tables (bottom). The white lines indicate where the top left of the screen currently is (where the two lines cross). The visual discontinuities are caused by the way the game streams the background into the name/attribute tables on demand, filling in only what's on screen in the frame; they're stale data. The color glitches result when the current color in the attribute table for an entry does not match some of the stale patterns still in that name table for that entry (e.g. on the far left the second column of patterns is discolored because they are stale and the attribute entry now corresponds to the first column of patterns, which is on screen).&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;The NES supports 64 sprites, each either 1 or 2 patterns in size (8x8 and 8x16, respectively), depending on whether a global flag is set. Analogous to the attribute table, each sprite contains the 2 high bits of color (though still that allows only 4 colors per sprite). Other info each sprite possesses includes position (obviously), mirroring parameters, and whether the sprite is in the foreground or background. However, even if you can have 64 sprites, the NES only supports 8 sprites per scan line; if there is more than that, only the 8 with the highest priority are drawn (smart games can cycle through their sprites each frame, but that results in flicker).&lt;br /&gt;&lt;br /&gt;There are, however, some tricks that can be done to circumvent some of the innate limitations (e.g. 16 colors, 16x16 blocks, 64 sprites, etc.). These often involve clever but perverse tricks related to swapping out the various things such as scroll offset or sprite data while drawing is underway. One common use of this is to draw part of the screen (the gameplay) with scrolling, while a portion of the screen on top or bottom is fixed (the score area). This can also be used to draw more than 64 sprites per frame, though there's still a limitation of only 8 sprites per scan line.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9GysFr4NPa4/So3Xd36oazI/AAAAAAAAAKI/4r9fYXcNzLQ/s1600-h/HardShellFight.gif"&gt;&lt;img style="cursor: pointer; width: 400px; height: 350px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/So3Xd36oazI/AAAAAAAAAKI/4r9fYXcNzLQ/s400/HardShellFight.gif" alt="" id="BLOGGER_PHOTO_ID_5372186838748916530" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Blaster Master and others frequently use the background as a grotesque way to draw very large sprites. In the above screen shot, the boss crab is actually the background, while the bubbles, player, and energy bars are sprites (the green areas of the boss are actually sprites, as well). The crab has a couple frames of animation; each of these is on a separate screen in the name table, and every frame the scrolling position is modified. This results in the crab moving around the screen and animating, as if it were a huge sprite.&lt;br /&gt;&lt;br /&gt;Oh, and in case you were wondering, yes, this boss frequently exceeds the 8 sprites per scan line limit (that would be 4 bubbles), resulting in the game slowing down to draw them all.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6096333270292980828?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6096333270292980828/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6096333270292980828' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6096333270292980828'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6096333270292980828'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/08/very-old-things-part-1.html' title='&amp; Very Old Things - Part 1'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_9GysFr4NPa4/SoybSHd8-eI/AAAAAAAAAKA/h8EpbjxOe6Q/s72-c/HardShellLarge.gif' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-1857970209674500986</id><published>2009-08-06T14:46:00.000-07:00</published><updated>2009-08-06T14:47:55.576-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><category scheme='http://www.blogger.com/atom/ns#' term='anime'/><title type='text'>&amp; Summer 2009 Anime Music</title><content type='html'>As with last season, I was again inspired to post theme songs that I like of current anime series. As with last season, one show's music in particular provided this inspiration - Umineko no Naku Koro ni [When the Seagulls Cry].&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Umineko no Naku Koro ni&lt;/span&gt; really walked away with the title of best theme music of the season, between the music not being bad, and the lack of any high-caliber competition. The opening especially appeals to me because one of the musical themes I go for is modern compositions/melodies in symphonic/operatic style. The ending I suppose would be classified as fun, in rock opera style with a singer that has the perfect voice to perform the the creepy insane rambling lyrics.&lt;br /&gt;&lt;br /&gt;Opening theme: Katayoku no Tori [One-Winged Bird]&lt;br /&gt;&lt;object height="280" width="450"&gt;&lt;param name="movie" value="http://www.youtube.com/v/bQLirU-cBws&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/bQLirU-cBws&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="280" width="450"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Ending theme: La Divina Tragedia&lt;br /&gt;&lt;object height="280" width="450"&gt;&lt;param name="movie" value="http://www.youtube.com/v/gU20fZdWIU4&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/gU20fZdWIU4&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="280" width="450"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Perhaps given the lack of serious competition I may have lowered the threshold for inclusion in this post, I dunno. Anyway, next up is &lt;span style="font-weight: bold;"&gt;Kara no Kyoukai [Boundary of Emptiness]: Garden of Sinners: Oblivion Recorder&lt;/span&gt;. Kara no Kyoukai is a series of movies that form a single plot line. While some of the themes are shared between all of the movies, some are unique to the movie (in this case the one that just came out a couple weeks ago).&lt;br /&gt;&lt;br /&gt;As you can see, the video was replaced with the logo of the movie. Note that I set it to start at 0:42, which is where the theme for this movie starts. The music before 0:42 and after 4:18 is from the main theme of Kara no Kyoukai, which I think it pretty bland.&lt;br /&gt;&lt;br /&gt;Ending theme: fairy tale&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/IOZjKaS5YU0&amp;amp;hl=en&amp;amp;fs=1&amp;amp;start=42"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/IOZjKaS5YU0&amp;amp;hl=en&amp;amp;fs=1&amp;amp;start=42" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;The rest all fall under the category of fun/cute. &lt;span style="font-weight: bold;"&gt;Bakemonogatari&lt;/span&gt; [translated by some as GhoStory, which preserves the pun] has a pretty fun ending theme with a bit of cuteness. The video of the credits seems to have been replaced with a still of the picture that's in the background during the credits.&lt;br /&gt;&lt;br /&gt;Ending theme: Kimi no Shiranai Monogatari [Your Strange Story]&lt;br /&gt;&lt;object height="270" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/I5IDb6O2k7k&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/I5IDb6O2k7k&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="270" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Yoku Wakaru Gendai Mahou&lt;/span&gt; [Comprehensible Modern Magic] has a somewhat peculiar ending theme. Like the animation during the credits (which you just know is going to get made into animated GIFs), the music is overly cute, yet strangely catchy (although I can imagine it would make some people want to kill things).&lt;br /&gt;&lt;br /&gt;Ending theme: Made in Wonder&lt;br /&gt;&lt;object height="280" width="450"&gt;&lt;param name="movie" value="http://www.youtube.com/v/UFnN7SkYb4I&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/UFnN7SkYb4I&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="280" width="450"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Finally, &lt;span style="font-weight: bold;"&gt;Hayate no Gotoku!!&lt;/span&gt; [Like the Wind; this is a pun on the main character's name being Hayate]; first of all, note that the sound on this video is LOUD, so you might want to turn your volume down. This one really crosses the line from cute into obnoxious. While the melody is nice and fun, the "cute" accompaniment makes me want to smash things.&lt;br /&gt;&lt;br /&gt;I can only figure that the producer of this series is an absolute copyright Nazi, because despite quite a bit of looking I can't find a single video of this ending theme with the credits animation, which is unfortunate, because that would show you who the infernal peanut gallery is. Instead, I found this video, and I really don't know where it came from. It's called a preview, but as I only saw one copy of it, I'm thinking maybe it's a fan-created anime music video. In either case, it seemed better than the large number of others, which simply played the music to some picture (the album cover, a picture of the character singing, etc.).&lt;br /&gt;&lt;br /&gt;Ending theme: Mankai Watashi Iro [something along the lines of My Full Bloom Form]&lt;br /&gt;&lt;object height="344" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/HXFCTdr4PQE&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/HXFCTdr4PQE&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="344" width="425"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-1857970209674500986?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/1857970209674500986/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=1857970209674500986' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1857970209674500986'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1857970209674500986'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/08/summer-2009-anime-music.html' title='&amp; Summer 2009 Anime Music'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-2076644868254922365</id><published>2009-08-03T18:13:00.000-07:00</published><updated>2011-07-04T16:47:13.857-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='anime'/><title type='text'>Introduction to Anime</title><content type='html'>As the amount I'm blogging has been decreasing for a while now, I'm noticing that the proportion I talk about anime is increasing significantly. For a while now I've listed the series I'm currently watching on the sidebar, and occasionally written anime-related posts (especially lately). This is all well and good if you're an anime watcher, and know basic things like how to find and download anime, but not so useful for people who don't know anything about anime (which are probably the majority of readers).&lt;br /&gt;&lt;br /&gt;So, I thought I should provide a very brief introduction. "Anime" is a nontechnical term for Japanese animation. Usually what we call cartoons are intended primarily for children, while anime has no such limitation; this frees anime up to represent just about anything you can come up with, including the more serious types of things that appear here in (filmed) movies and television. Apart from that, anime is vaguely defined by the Japanese cultural themes present in it, which may give it a different feel than our cartoons, movies, or TV shows. One theme that's conspicuously absent in anime is the strong bias to have fictional stories take place in something resembling the real world, resulting in a lot more variation in setting and less adherence to realism in anime than in our movies/TV.&lt;br /&gt;&lt;br /&gt;Okay, that wasn't as brief as I was hoping for. Next topic: where to check out anime, if you haven't seen it before (or if you've only seen cartoony children's anime). Specifically, the rest of this post is a listing of free, legal anime series available for streaming online. Generally the quality of streamed episodes isn't near as good as episodes you download, but it has the advantage of allowing you to watching instantly without having to download hundreds of megs in advance (not to mention that I don't know of any free, fully legal sources of downloadable high).&lt;br /&gt;&lt;br /&gt;How this works is that I've essentially gone through all the streaming sites I know and made a list of all the series I've seen (or at least the ones that didn't suck so bad I'm not even willing to admit to watching them) and their genres. I threw in a couple series (marked with a *) that I haven't seen, simply because they're phenomenally popular and no list of anime would be complete without them. As anime dubs are often almost as bad as Japanese actors trying to speak English (occasionally seen in anime), I've only included links to dubbed series (marked with D) when there is no alternate subbed version available.&lt;br /&gt;&lt;br /&gt;The genres listed are (supposedly) in order from most to least meaningful, but are all off the top of my head; as I haven't seen some of these series in many years (and some not at all), accuracy is not guaranteed (and of course it's always possible that I might simply have mislabeled something on accident). I've defined "fantasy" pretty broadly, so as to include stuff outside the typical Lord of the Rings type story (e.g. I include supernatural). "Slice of life" refers to series centered around the daily lives and activities of the main characters (most commonly school), where the activities usually resemble the life of the intended watcher to some extent. Here I use "fighting" in contrast with "action", where the former refers to things that are substantially composed of a progressive series of fights between the protagonists and antagonists (usually duels, often with named attacks, etc.), while the latter often has more general battle scenes (such as shoot-outs).&lt;br /&gt;&lt;br /&gt;&lt;a name="list"&gt;The ones I liked most, and would most recommend:&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/CODE_GEASS_Lelouch_of_the_Rebellion" title="CODE GEASS Lelouch of the Rebellion"&gt;CODE GEASS Lelouch of the Rebellion&lt;/a&gt;. Drama, comedy, mecha, action. Note that while I and a large number of others liked it a lot, it's pretty hit or miss with people, so your mileage may vary.&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/death-note?c=Animation-and-Cartoons" class="info_hover observing"&gt;Death Note&lt;/a&gt;. Drama, mystery, supernatural&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Durarara"&gt;Durarara!!&lt;/a&gt;.  Fantasy, drama, action&lt;br /&gt;&lt;a href="http://www.hulu.com/full-metal-panic"&gt;Full Metal Panic!&lt;/a&gt;  Comedy, military, action, mecha&lt;br /&gt;&lt;a href="http://www.hulu.com/full-metal-panic-fumoffu"&gt;Full Metal Panic?  Fumoffu&lt;/a&gt; [sequel]&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/fullmetal-alchemist-brotherhood?c=Animation-and-Cartoons" class="info_hover observing"&gt;Fullmetal Alchemist: Brotherhood&lt;/a&gt;.  Drama, fantasy, fighting, military&lt;br /&gt;&lt;a href="http://www.hulu.com/gunslinger-girl?c=Animation-and-Cartoons/Anime"&gt;Gunslinger Girl&lt;/a&gt;. Action, drama&lt;br /&gt;&lt;a href="http://www.hulu.com/gunslinger-girl-il-teatrino?c=Animation-and-Cartoons/Anime"&gt;Gunslinger  Girl: Il Teatrino&lt;/a&gt; [sequel]. Action, drama&lt;br /&gt;&lt;a href="http://www.hulu.com/when-they-cry?c=Animation-and-Cartoons/Anime"&gt;Higurashi - When They Cry&lt;/a&gt;. Mystery, horror, comedy, drama, ecchi (D)&lt;br /&gt;&lt;a href="http://www.hulu.com/hikaru-no-go?c=Animation-and-Cartoons/Anime"&gt;Hikaru no Go&lt;/a&gt;. Gaming, comedy, drama&lt;br /&gt;&lt;a href="http://www.animenewsnetwork.com/video/3621/"&gt;Kannagi&lt;/a&gt;. Comedy, supernatural, slice of life&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Last_Exile" title="Last Exile"&gt;Last Exile&lt;/a&gt;. Scifi/fantasy, drama, action&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/The_Melancholy_of_Haruhi_Suzumiya"&gt;The Melancholy of Haruhi Suzumiya&lt;/a&gt;. Comedy, parody&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/mushi-shi?c=Animation-and-Cartoons" class="info_hover observing"&gt;Mushi-shi&lt;/a&gt;. Supernatural, drama (D)&lt;br /&gt;&lt;a href="http://www.hulu.com/noir"&gt;Noir&lt;/a&gt;. Action, drama&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/school-rumble?c=Animation-and-Cartoons"&gt;School Rumble&lt;/a&gt;. Comedy, slice of life, romance (D)&lt;br /&gt;&lt;a href="http://www4.funimation.com/video/?page=show&amp;amp;b=288"&gt;Spice and Wolf&lt;/a&gt; (both seasons). Fantasy, medieval, slice of life, comedy&lt;br /&gt;&lt;br /&gt;The rest I've seen:&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/5_Centimeters_per_Second" title="5 Centimeters per Second"&gt;5 Centimeters per Second&lt;/a&gt;. Drama&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/11Eyes"&gt;11 Eyes&lt;/a&gt;. Fantasy, fighting, drama, ecchi&lt;br /&gt;&lt;a href="http://www4.funimation.com/video/?page=show&amp;amp;b=175"&gt;Air&lt;/a&gt;. Romance, fantasy, tragedy&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Asura_Cryin"&gt;Asura Cryin&lt;/a&gt;. Scifi/fantasy, fighting, mecha, drama&lt;br /&gt;&lt;a href="http://www.hulu.com/aria-the-scarlet-ammo"&gt;Aria the Scarlet Ammo&lt;/a&gt;. Action, comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/baka-and-test-summon-the-beasts?c=Animation-and-Cartoons/Anime"&gt;Baka and Test - Summon the Beasts&lt;/a&gt;. Comedy, fantasy/scifi, fighting, ecchi&lt;br /&gt;&lt;a href="http://www4.funimation.com/video/?page=show&amp;amp;b=186"&gt;Bamboo Blade&lt;/a&gt;. Martial arts, slice of life, comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/beck-mongolian-chop-squad?c=Animation-and-Cartoons/Anime"&gt;Beck: Mongolian Chop Squad&lt;/a&gt;. Music, drama&lt;br /&gt;&lt;a href="http://www.hulu.com/black-butler"&gt;Black Butler&lt;/a&gt;. Supernatural, comedy, action&lt;br /&gt;&lt;a href="http://www.hulu.com/black-butler-ii?c=Animation-and-Cartoons/Anime"&gt;Black Butler II&lt;/a&gt; [sequel]&lt;br /&gt;&lt;a href="http://www.hulu.com/bleach?c=Animation-and-Cartoons" class="info_hover observing"&gt;Bleach&lt;/a&gt;. Fighting, supernatural, comedy&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/The_Book_of_Bantorra"&gt;Book of Bantorra&lt;/a&gt;. Fantasy, action&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/a-bridge-to-the-starry-skies-hoshizora-e-kakaru-hashi"&gt;A Bridge to the Starry Sky&lt;/a&gt;. Romance, comedy, ecchi&lt;br /&gt;&lt;a href="http://www.hulu.com/buso-renkin?c=Animation-and-Cartoons/Anime"&gt;Busou Renkin&lt;/a&gt;. Fighting, fantasy, comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/c-control"&gt;C&lt;/a&gt;. Drama, fighting, fantasy&lt;br /&gt;&lt;a href="http://www.hulu.com/canaan"&gt;Canaan&lt;/a&gt;. Action, military&lt;br /&gt;&lt;a href="http://www.hulu.com/chrome-shelled-regios"&gt;Chrome Shelled Regios&lt;/a&gt;. Sci-fi/fantasy, military, action&lt;br /&gt;&lt;a href="http://www.hulu.com/claymore?c=Animation-and-Cartoons/Anime"&gt;Claymore&lt;/a&gt;. Fighting, fantasy&lt;br /&gt;&lt;a href="http://www.hulu.com/cross-game"&gt;Cross Game&lt;/a&gt;. Sports, comedy, slice of life&lt;br /&gt;&lt;a href="http://www.hulu.com/d-gray-man?c=Animation-and-Cartoons/Anime"&gt;D.Gray-Man&lt;/a&gt;. Fighting, supernatural, comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/dance-in-the-vampire-bund?c=Animation-and-Cartoons/Anime"&gt;Dance in the Vampire Bund&lt;/a&gt;. Fantasy, drama, action, ecchi&lt;br /&gt;&lt;a href="http://www.hulu.com/darker-than-black?c=Animation-and-Cartoons/Anime"&gt;Darker than Black&lt;/a&gt;. Fighting, fantasy/scifi&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/deadman-wonderland"&gt;Deadman Wonderland&lt;/a&gt;. Drama, action&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/dragon-crisis"&gt;Dragon Crisis&lt;/a&gt;. Fantasy, action, comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/eden-of-the-east?c=Animation-and-Cartoons/Anime"&gt;Eden of the East&lt;/a&gt;. Drama, romance, scifi&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Erin"&gt;Erin&lt;/a&gt;. Fantasy, slice of life, drama&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/fortune-arterial"&gt;Fortune Arterial&lt;/a&gt;. Slice of life, supernatural, romance&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/full-metal-panic-the-second-raid?c=Animation-and-Cartoons"&gt;Full Metal Panic! The Second Raid&lt;/a&gt; [sequel]&lt;br /&gt;&lt;a href="http://www.hulu.com/fullmetal-alchemist?c=Animation-and-Cartoons/Anime"&gt;Fullmetal Alchemist&lt;/a&gt; [alternate]&lt;br /&gt;&lt;a href="http://www.hulu.com/fractale"&gt;Fractale&lt;/a&gt;. Sci-fi, drama, action&lt;br /&gt;&lt;a href="http://www.funimation.com/fruitsbasket/"&gt;Fruits Basket&lt;/a&gt;. Fantasy, slice of life, comedy (D)&lt;br /&gt;&lt;a href="http://www.hulu.com/ghost-hunt?c=Animation-and-Cartoons/Anime"&gt;Ghost Hunt&lt;/a&gt;. Supernatural, horror, drama, mystery&lt;br /&gt;&lt;a href="http://www.hulu.com/ghost-hound"&gt;Ghost Hound&lt;/a&gt;. Supernatural, mystery, psychological&lt;br /&gt;&lt;a href="http://www.hulu.com/golgo-13"&gt;Golgo 13&lt;/a&gt;. Action&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/gosick"&gt;Gosick&lt;/a&gt;. Mystery&lt;br /&gt;&lt;a href="http://www.animenewsnetwork.com/video/1605/"&gt;Gundam 00&lt;/a&gt;. Scifi, mecha, action, drama*&lt;br /&gt;&lt;a href="http://www.hulu.com/gurren-lagann?c=Animation-and-Cartoons/Anime"&gt;Gurren Lagann&lt;/a&gt;. Mecha, scifi, action, comedy (D)&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/hanasaku-iroha"&gt;Hanasaku Iroha&lt;/a&gt;. Slice of life, drama, comedy&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Hayate_no_Gotoku_%21"&gt;Hayate no Gotoku!&lt;/a&gt; Comedy, parody, fighting&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/hayate"&gt;Hayate no Gotoku!!&lt;/a&gt; [sequel]&lt;br /&gt;&lt;a href="http://www.hulu.com/his-and-her?c=Animation-and-Cartoons/Anime"&gt;His and Her Circumstances&lt;/a&gt;. Slice of life, comedy, romance&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/honey-and-clover?c=Animation-and-Cartoons" class="info_hover observing"&gt;Honey and Clover&lt;/a&gt;. Drama, slice of life&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Hyakko" title="Hyakko"&gt;Hyakko&lt;/a&gt;. Comedy, slice of life&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/inuyasha?c=Animation-and-Cartoons" class="info_hover observing"&gt;InuYasha&lt;/a&gt;. Fantasy, drama, comedy, fighting&lt;br /&gt;&lt;a href="http://www.hulu.com/inuyasha-the-final-act?c=Animation-and-Cartoons/Anime"&gt;InuYasha: The Final Act&lt;/a&gt; [sequel]&lt;br /&gt;&lt;a href="http://www4.funimation.com/video/?page=show&amp;amp;b=45"&gt;Kanon&lt;/a&gt;. Slice of life, romance, comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/kaze-no-stigma?c=Animation-and-Cartoons/Anime"&gt;Kaze no Stigma&lt;/a&gt;. Fantasy, fighting, comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/kimikisspure-rouge"&gt;Kimikiss: Pure Rouge&lt;/a&gt; #. Slice of life, romance&lt;br /&gt;&lt;a href="http://www.hulu.com/kinos-journey"&gt;Kino's Journey&lt;/a&gt; #. Fantasy, philosophy&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/kore-wa-zombie-desu-ka"&gt;Kore wa Zombie Desu ka&lt;/a&gt;. Fantasy, comedy, action, ecchi&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Kurokami_The_Animation" title="Kurokami The Animation"&gt;Kurokami The Animation&lt;/a&gt;. Fighting, martial arts, drama&lt;br /&gt;&lt;a href="http://www.hulu.com/the-legend-of-the-legendary-heroes"&gt;The Legend of the Legendary Heroes&lt;/a&gt;. Fantasy, comedy, action&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/lucky-star"&gt;Lucky Star&lt;/a&gt;. Comedy, parody, slice of life&lt;br /&gt;&lt;a href="http://www.animenewsnetwork.com/video/15091/"&gt;Maria Holic&lt;/a&gt;. Comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/naoki-urasawas-monster?c=Animation-and-Cartoons/Anime"&gt;Monster&lt;/a&gt;. Drama, horror (D)&lt;br /&gt;&lt;a href="http://www.hulu.com/moon-phase"&gt;Moon Phase&lt;/a&gt;. Supernatural, fighting, comedy, romance&lt;br /&gt;&lt;a href="http://www.hulu.com/my-bride-is-a-mermaid?c=Animation-and-Cartoons/Anime"&gt;My Bride Is a Mermaid&lt;/a&gt;. Comedy, fantasy, parody, ecchi&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/my-ordinary-life"&gt;My Ordinary Life&lt;/a&gt;. Comedy, slice of life&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Myself_Yourself" title="Myself Yourself"&gt;Myself Yourself&lt;/a&gt;. Comedy, slice of life, romance&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Naruto" title="Naruto"&gt;Naruto&lt;/a&gt;. Fighting, martial arts, drama, fantasy,  comedy*&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Naruto_Shippuden" title="Naruto Shippuden"&gt;Naruto Shippuden&lt;/a&gt; [sequel]*&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/NATSU_NO_ARASHI_%21" title="NATSU NO ARASHI !"&gt;NATSU NO ARASHI!&lt;/a&gt; Comedy, supernatural&lt;br /&gt;&lt;a href="http://www.hulu.com/negima?c=Animation-and-Cartoons/Anime"&gt;Negima!&lt;/a&gt; Fantasy, comedy, ecchi, fighting,&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Nogizaka_Haruka_no_Himitsu"&gt;Nogizaka Haruka no Himitsu&lt;/a&gt;. Comedy, romance, ecchi&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/occultacademy"&gt;Occult Academy&lt;/a&gt;. Supernatural, scifi, mystery, action, comedy&lt;br /&gt;&lt;a href="http://www.funimation.com/okamisan/episodes"&gt;Okamisan&lt;/a&gt;. Comedy, slice of life, parody&lt;br /&gt;&lt;a href="http://www.hulu.com/one-piece?c=Animation-and-Cartoons/Anime"&gt;One Piece&lt;/a&gt;. Comedy, action, fantasy*&lt;br /&gt;&lt;a href="http://www.animenewsnetwork.com/video/9457/"&gt;Oreimo&lt;/a&gt;. Comedy, parody&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/demon-girl-zakuro"&gt;Otome Yokai Zakuro&lt;/a&gt;. Supernatural, comedy, romance&lt;br /&gt;&lt;a href="http://www.animenewsnetwork.com/video/11951/"&gt;Pandora Hearts&lt;/a&gt;. Fantasy, comedy, action&lt;br /&gt;&lt;a href="http://www4.funimation.com/video/?page=show&amp;amp;b=68"&gt;Pani Poni Dash&lt;/a&gt;. Comedy, school life, parody&lt;br /&gt;&lt;a href="http://www.hulu.com/princess-jellyfish"&gt;Princess Jellyfish&lt;/a&gt;. Comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/pumpkin-scissors?c=Animation-and-Cartoons/Anime"&gt;Pumpkin Scissors&lt;/a&gt;. Military, drama, comedy, action (D)&lt;br /&gt;&lt;a href="http://www.hulu.com/rideback"&gt;Rideback&lt;/a&gt;. Mecha, drama, military&lt;br /&gt;&lt;a href="http://www.hulu.com/rod-the-tv"&gt;R.O.D. The TV&lt;/a&gt;. Fantasy/scifi, action&lt;br /&gt;&lt;a href="http://www.hulu.com/rumbling-hearts?c=Animation-and-Cartoons/Anime"&gt;Rumbling Hearts&lt;/a&gt;. Drama, comedy, ecchi&lt;br /&gt;&lt;a href="http://www.hulu.com/the-sacred-blacksmith?c=Animation-and-Cartoons/Anime"&gt;Sacred Blacksmith&lt;/a&gt;. Fantasy, action, comedy, ecchi&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Saki" title="Saki"&gt;Saki&lt;/a&gt;. Gaming, drama, comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/samurai-x?c=Animation-and-Cartoons/Anime"&gt;Samurai X&lt;/a&gt; [AKA Rurouni Kenshin]. Martial arts, fighting, comedy, drama (D)&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Sasameki_Koto"&gt;Sasameki Koto&lt;/a&gt;. Comedy, slice of life&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/student-councils-discretion"&gt;Seitokai no Ichizon - Student Council's Discretion&lt;/a&gt;. Comedy, parody&lt;br /&gt;&lt;a href="http://www4.funimation.com/video/?page=show&amp;amp;b=83"&gt;Shana&lt;/a&gt;. Fighting, supernatural, comedy (D)&lt;br /&gt;&lt;a href="http://www.hulu.com/shigofumi?c=Animation-and-Cartoons/Anime"&gt;Shigofumi: Letters from the Departed&lt;/a&gt; #. Drama, supernatural, psychological&lt;br /&gt;&lt;a href="http://www.hulu.com/shiki?c=Animation-and-Cartoons/Anime"&gt;Shiki&lt;/a&gt;. Mystery, horror, fantasy&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/SHANGRI-LA" title="SHANGRI-LA"&gt;SHANGRI-LA&lt;/a&gt;. Drama, scifi, action&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/sket-dance"&gt;SKET Dance&lt;/a&gt;. Comedy, action&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Sketchbook"&gt;Sketchbook&lt;/a&gt;. Comedy, slice of life&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Skip_Beat%21" title="Skip Beat!"&gt;Skip Beat!&lt;/a&gt; Drama, comedy, romance&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/slayers?c=Animation-and-Cartoons" class="info_hover observing"&gt;Slayers&lt;/a&gt;. Fantasy, fighting, drama (D)&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/the-slayers-next?c=Animation-and-Cartoons" class="info_hover observing"&gt;Slayers NEXT&lt;/a&gt; [sequel] (D)&lt;br /&gt;&lt;a href="http://www.hulu.com/slayers-revolution?c=Animation-and-Cartoons/Anime"&gt;Slayers Revolution&lt;/a&gt; [sequel]&lt;br /&gt;&lt;a href="http://www.hulu.com/slayers-evolution-r?c=Animation-and-Cartoons/Anime"&gt;Slayers Evolution-R&lt;/a&gt; [sequel]&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Soranowoto"&gt;Sora no Woto&lt;/a&gt;. Slice of life, military, comedy&lt;br /&gt;&lt;a href="http://www.hulu.com/special-a"&gt;Special A&lt;/a&gt; #. Comedy, slice of life, romance&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/squid-girl"&gt;Squid Girl&lt;/a&gt;. Comedy&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/steinsgate"&gt;STEINS;GATE&lt;/a&gt;. Scifi, drama&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/strain-stategic-armored-infantry?c=Animation-and-Cartoons"&gt;Strain: Strategic Armored Infantry&lt;/a&gt;. Action, scifi, mecha, drama&lt;br /&gt;&lt;a href="http://www.hulu.com/tears-to-tiara?c=Animation-and-Cartoons/Anime"&gt;Tears to Tiara&lt;/a&gt;. Fantasy, drama, action&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/library/Tegami_Bachi:_Letter_Bee"&gt;Tegami Bachi: Letter Bee&lt;/a&gt;. Fantasy, action&lt;br /&gt;&lt;a href="http://www.hulu.com/trigun?c=Animation-and-Cartoons/Anime"&gt;Trigun&lt;/a&gt;. Action, comedy, scifi&lt;br /&gt;&lt;a href="http://www.hulu.com/vampire-knight?c=Animation-and-Cartoons/Anime"&gt;Vampire Knight&lt;/a&gt;. Supernatural, drama&lt;br /&gt;&lt;a href="http://www.hulu.com/vandread?c=Animation-and-Cartoons/Anime"&gt;Vandread&lt;/a&gt;. Scifi, mecha, comedy, ecchi, action&lt;br /&gt;&lt;a href="http://www4.funimation.com/video/?page=show&amp;amp;b=64"&gt;Welcome to the NHK&lt;/a&gt;. Comedy, drama, psychological (D)&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/whitealbum"&gt;White Album&lt;/a&gt;. Drama, romance&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/the-world-god-only-knows"&gt;The World Only God Knows&lt;/a&gt;. Supernatural, school life, comedy, romance&lt;br /&gt;&lt;a id="" href="http://www.hulu.com/xxxholic?c=Animation-and-Cartoons" class="info_hover observing"&gt;xxxHolic&lt;/a&gt; ['xxx' seems to refer to the supernatural, here]. Supernatural, drama (D)&lt;br /&gt;&lt;br /&gt;Finally, the list of noteworthy free, legal anime sites, listed from largest selection to smallest:&lt;br /&gt;&lt;a href="http://www.animenewsnetwork.com/video/anime"&gt;Anime News Network&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.crunchyroll.com/"&gt;Crunchyroll&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.hulu.com/"&gt;Hulu&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www4.funimation.com/video/"&gt;Funimation&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.joost.com/"&gt;Joost&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-2076644868254922365?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/2076644868254922365/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=2076644868254922365' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2076644868254922365'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2076644868254922365'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/08/introduction-to-anime.html' title='Introduction to Anime'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-9010046125209352792</id><published>2009-07-27T20:25:00.000-07:00</published><updated>2009-07-27T20:28:47.991-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='anime'/><title type='text'>&amp; Summer 2009 Thoughts</title><content type='html'>So, we're now several episodes into the summer 2009 anime season. I've been meaning to write mini-reviews of new series for a few seasons, now, but never got around to it; we'll see if I actually make it to the end of (writing) this post, this time.&lt;br /&gt;&lt;br /&gt;First of all, I always get my first looks at new series from Random Curiosity's &lt;a href="http://randomc.animeblogger.net/2009/06/24/summer-2009-preview/"&gt;season previews&lt;/a&gt;. and I'll probably end up quoting some of their descriptions here (and go in the order they're listed in the preview). With the exception of one, all the ones I'm going to list here piqued my interest at least enough to give them a shot (at least the first episode).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6481"&gt;Charger Girl Ju-den Chan&lt;/a&gt; [that's the official English name on &lt;a href="http://www.crunchyroll.com/library/Charger_Girl_Ju-den_Chan"&gt;CrunchyRoll&lt;/a&gt;; it's listed as Fight Ippatsu! Juuden-chan!! on the preview]&lt;br /&gt;&lt;br /&gt;Preview says:&lt;br /&gt;&lt;blockquote&gt;Let me start by saying that I’m not convinced that this series is anything other than a vehicle for fanservice and nudity. Originally by the author of Mahoromatic and KissXsis, Juuden-chan is a story about a clumsy girl whose job it is to inject energy into people who are depressed. If that doesn’t tip you off on what kind of series this’ll be, then maybe a visit to the official site where you can remove some of the main character’s clothing will. And then there’s the promo video (see below) that’s got the main character orgasming during a transformation sequence.&lt;br /&gt;&lt;/blockquote&gt;Verdict: who could say no to that? Me, for one.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6051"&gt;Umineko no Naku Koro ni&lt;/a&gt; [When the Seagulls Cry]&lt;br /&gt;Genre: mystery, drama, psychological&lt;br /&gt;"Sequel" to &lt;a href="http://en.wikipedia.org/wiki/Higurashi_no_Naku_Koro_ni"&gt;Higurashi no Naku Koro ni&lt;/a&gt; [When the Cicadas Cry], another mystery murder series, about a rich family getting together to hash out the details of their inheritance after the patriarch dies. From there things quickly go downhill, as six people are murdered on the first night.&lt;br /&gt;&lt;br /&gt;Higurashi, as I mentioned, was quite a strange series. I didn't particularly like the characters, nor did I like some of the excessively slapstick comedy [OMGWTF @ &lt;a href="http://wakaranai.animeblogger.net/?p=768"&gt;Higurashi Rei 1&lt;/a&gt;], but it had an awesome and intelligent high-level story, and it was told very well. As such, I liked Higurashi as a whole, and I've been waiting for Umineko ever since I heard about it (it was originally a game, like the Higurashi series). So far it seems to be more drama than comedy, although there's also been some of that.&lt;br /&gt;&lt;br /&gt;By the way, I hear that the Higurashi games have just &lt;a href="http://www.animenewsnetwork.com.au/news/2009-07-05/mangagamer.com-acquires-when-they-cry-higurashi-visual-novels"&gt;been licensed&lt;/a&gt;, and will be released in English pretty soon.&lt;br /&gt;Verdict: definitely watching&lt;br /&gt;&lt;br /&gt;&lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6315"&gt;Taishou Yakyuu Musume&lt;/a&gt; [&lt;a href="http://en.wikipedia.org/wiki/Taish%C5%8D_period"&gt;Taishou&lt;/a&gt; Baseball Girls]&lt;br /&gt;Genre: slice of life, comedy&lt;br /&gt;&lt;br /&gt;High school girls forming a baseball team in the early 1900s. I was/am pretty wary about this one. I've seen entirely too many (which is to say a few) "cute girls do (often boy) things in cute ways" series that rely on girls being cute as the primary attraction (a genre I've named Shoukawa). E.g. while I did watch and enjoy "the definition of moe" &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6257"&gt;K-ON!&lt;/a&gt; (girls forming a rock band) last season, it really had entirely too much &lt;a href="http://en.wikipedia.org/wiki/Moe_%28slang%29"&gt;moe&lt;/a&gt;, and I would have liked it more if it had less.&lt;br /&gt;&lt;br /&gt;There was, however, a shred of hope with this series. Japan is in some ways even more conservative than the US, so it would be unheard of for there to be a girls' baseball team in that time (e.g. how in the first episode one girl refers to baseball as "that thing boys do"). If they could create a realistic depiction of the cultural and social clash of something like this (as opposed to simply saying "Here's some cute girls doing funny things! Watch!"), that could be interesting enough to justify watching it. So I decided to take a look and see.&lt;br /&gt;&lt;br /&gt;Well, thus far only the first episode has been translated by a decent group, so that's all I have to go on. It wasn't bad, to sum up in a couple words. There were indeed signs of exploiting moe, but there were also signs of interesting cultural material - enough to keep my hopes alive, for the moment. I'll know more after a couple more episodes.&lt;br /&gt;Verdict: still watching&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_9GysFr4NPa4/Sm4AJEJPMNI/AAAAAAAAAJg/9OHMtioMbyE/s1600-h/snapshot20090727122909.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 300px;" src="http://4.bp.blogspot.com/_9GysFr4NPa4/Sm4AJEJPMNI/AAAAAAAAAJg/9OHMtioMbyE/s400/snapshot20090727122909.jpg" alt="" id="BLOGGER_PHOTO_ID_5363224361976148178" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Two of the girls (the rest all ran away immediately) on a field trip to watch boys play baseball, after seeing the batter nail the pitcher in the head with the ball.&lt;/span&gt;&lt;br /&gt;&lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6327"&gt;&lt;br /&gt;Bakemonogatari&lt;/a&gt; [I'm told this is wordplay on 'bakemo monogatari', which would be something like Supernatural Story]&lt;br /&gt;Genre: supernatural/mythology, comedy, randomness&lt;br /&gt;&lt;br /&gt;This one I hadn't really planned to watch, though I decided to take a look after some of the WTF stuff in the &lt;a href="http://randomc.animeblogger.net/2009/07/04/bakemonogatari-01/"&gt;first episode summary&lt;/a&gt; on Random Curiosity (the girl &lt;a href="http://randomc.maximum7.net/image/Bakemonogatari/Bakemonogatari%20-%2001%20-%20Large%2010.jpg"&gt;stapling the guy's cheek&lt;/a&gt; comes readily to mind). It's a rather weird story about a guy who encounters a number of supernatural phenomena in his daily life; in the past he himself had been a vampire, and in the time of the series he encounters a number of girls with various supernatural problems. Sounds like a dating sim adaptation to me (which was part of why I didn't initially intend to watch it), though I really hope that's not the case, as the second girl has to be in elementary school.&lt;br /&gt;Verdict: still watching. I don't know if I'd say it's good; but I really hate to drop series after I've watched a few episodes, and it hasn't been bad enough to do that. It really doesn't help that it's by SHAFT, who I rather dislike; they can certainly draw pretty pictures (as you can see in the summary), but they have an incredibly distinctive artistic style that I find quite disorienting and relatively difficult to follow.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_9GysFr4NPa4/Sm4BAmGosJI/AAAAAAAAAJo/UYP6BKXu2fQ/s1600-h/31885.jpg"&gt;&lt;img style="cursor: pointer; width: 294px; height: 400px;" src="http://3.bp.blogspot.com/_9GysFr4NPa4/Sm4BAmGosJI/AAAAAAAAAJo/UYP6BKXu2fQ/s400/31885.jpg" alt="" id="BLOGGER_PHOTO_ID_5363225315984846994" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Girl #1. She can probably kill you with each of those.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6275"&gt;Canaan&lt;/a&gt; [main character's name]&lt;br /&gt;Genre: action, drama, fighting&lt;br /&gt;&lt;br /&gt;Another series about an inhumanly good gunfighter girl with underworld dealings, lots of action and gunfights, and something about bio-terrorism. It sure sounds (and looks, thus far) like its girls-with-guns predecessors &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=13"&gt;Noir&lt;/a&gt; and &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=1654"&gt;Madlax&lt;/a&gt;, though as far as I can tell it's not by any of the same people. As a matter of fact, it's an adaptation of a video game, so I suppose the fact that it seems pretty decent to even people who haven't played the game is noteworthy.&lt;br /&gt;Verdict: pretty decent&lt;br /&gt;&lt;br /&gt;&lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6531"&gt;Kanamemo&lt;/a&gt; [not too sure about this one; Kana could be the main character's name, but the only thing I could think of for "memo" is some misapplication of the English word to refer to newspapers]&lt;br /&gt;Genre: comedy, slice of life&lt;br /&gt;&lt;br /&gt;Story of an orphan girl who gets hired to work and live at a newspaper delivery place, and her daily life. That was enough to make me take a look, as slice of life comedies are one of the things I'm most into. While it's always possible I'm not giving it enough of a chance, the one episode I saw lead me to believe it was merely the sum of it's parts, as listed by AniDB (categories): coming of age, large breasts, lolicon [pedophilic], shoujo ai [lesbian], small breasts.&lt;br /&gt;Verdict: taking my ball and going home. Perhaps if I'm ever desperate for something to watch I might see if the second episode was like the first; but not any time soon.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6398"&gt;Sora no Manimani&lt;/a&gt; [Following the Sky? This is a really tricky name to crack, for somebody with limited knowledge of Japanese]&lt;br /&gt;Genre: comedy, slice of life, romance&lt;br /&gt;&lt;br /&gt;Another slice of life comedy, this time about a small astronomy club at a high school. Of course this one also caught my attention for something to at least check out. Out of the first two episodes it seems pretty average, as far as slice of life comedies go, though it's difficult to come up with something more cliche in anime than the harem [multiple girls that all like the male main character]. This will probably end up in the slot of "something to watch when I'm out of better stuff to watch".&lt;br /&gt;Verdict: better than nothing&lt;br /&gt;&lt;br /&gt;&lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6169"&gt;Spice and Wolf II&lt;/a&gt;&lt;br /&gt;Genre: drama, comedy, romance, medieval slice of life&lt;br /&gt;&lt;br /&gt;Based on a series of novels, this series is about a traveling merchant in the middle ages and his (sage wolf god) traveling companion. This is one of those series that features more mature topics than most, such as economics and politics. I liked the first season of it a couple years ago, and I've been looking forward to a second season ever since. If you're looking for something outside the ordinary anime, this is one to consider.&lt;br /&gt;Verdict: good&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_9GysFr4NPa4/Sm4CxTa-J7I/AAAAAAAAAJw/V2RXG1c82bU/s1600-h/snapshot20090724190246.jpg"&gt;&lt;img style="cursor: pointer; width: 400px; height: 225px;" src="http://4.bp.blogspot.com/_9GysFr4NPa4/Sm4CxTa-J7I/AAAAAAAAAJw/V2RXG1c82bU/s400/snapshot20090724190246.jpg" alt="" id="BLOGGER_PHOTO_ID_5363227252295083954" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;Wolf and hangover. In case anybody is wondering, these are all pictures I took while watching the series, not ones taken specifically for this post.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6332"&gt;Yoku Wakaru Gendai Mahou&lt;/a&gt; [something like Modern Day Magic to Be Well Learned]&lt;br /&gt;Genre: comedy, fantasy&lt;br /&gt;&lt;br /&gt;In this world, like in &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=99"&gt;Serial Experiments Lain&lt;/a&gt;, reality is fundamentally composed of information, and like data in a computer this information can be altered; this is the nature of magic. I thought that creative take on magic was interesting enough to warrant checking out. Unfortunately, the first two episodes lead me to believe that an interesting premise is all this show has going for it, and in general it appears to be a dud; and with an average rating of 6.4 out of 10, it seems like a lot of people concur.&lt;br /&gt;Verdict: on life support. If I'm feeling generous, I might watch the third episode (next week) and see if it manages to improves any.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-9010046125209352792?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/9010046125209352792/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=9010046125209352792' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/9010046125209352792'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/9010046125209352792'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/07/summer-2009-thoughts.html' title='&amp; Summer 2009 Thoughts'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_9GysFr4NPa4/Sm4AJEJPMNI/AAAAAAAAAJg/9OHMtioMbyE/s72-c/snapshot20090727122909.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-8834456886510824613</id><published>2009-07-26T14:00:00.000-07:00</published><updated>2009-07-26T14:08:16.994-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>&amp; That Memory Leak</title><content type='html'>I'm pretty sure that a while back I mentioned a particular Firefox plugin called &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/4869"&gt;Feed Sidebar&lt;/a&gt;. It's a nice little RSS feed plugin that does exactly what I wanted an RSS plugin to do (and all others work differently). As such, I'm rather fond of it, and have been rather tolerant of its faults.&lt;br /&gt;&lt;br /&gt;The particular fault I believe I discussed was that it leaked memory. With the ~15 RSS feeds I have on it set to update every 10 minutes, it leaked about 20 megs of memory per hour. While many would probably not find this to be a serious problem (e.g. 8 hours x 20 megs/hour = 160 megs leaked before shutting down for the day), as I tend to leave my computer running for weeks straight, this was a moderate annoyance. Left on its own, Firefox would crash about every three days due to address space exhaustion (32-bit applications have a 2 gig address space, and fragmentation can reduce the amount actually allocatable below that; I was seeing it crash around 1.5 gigs). Much more frequently, I'd start World of Warcraft and my computer would grind to a halt, as Windows really, really doesn't like it when you get &gt; 90% memory usage (up until a month or two ago, when I have 4 gigs of RAM), and I'd have to manually restart Firefox at that point.&lt;br /&gt;&lt;br /&gt;On one occasion I e-mailed the author about the problem; he said that he'd been looking for the leak for a while, and was stumped. Unfortunately, as I haven't done anything with Javascript (what Firefox plugins are written in) in over a decade, and I don't know the first thing about the Firefox plugin architecture, I couldn't go looking for the problem myself as I've done so many times in the past (at least 3 or 4 incidents on the blog).&lt;br /&gt;&lt;br /&gt;However, a couple weeks ago the problem suddenly become much worse. Immediately after installing Firefox 3.5, I noticed that it was now hemorrhaging about 150 megs/hour, more than seven times as fast as in 3.0 and earlier (in fact, at first I thought it was that 3.5 was just unstable, as it crashed about every day; then I noticed that it was allocating massive amounts of memory). After verifying both that this was consistent/reproducible and that this was indeed due to the particular addon, I e-mailed the author again, with my new data.&lt;br /&gt;&lt;br /&gt;Apparently that got a pretty quick response. A couple days later he sent me a test build he wanted me to try. After some looking, he'd come to believe that there was a bug in Firefox that was leaking SQLite resources; resources that should have been freed when an SQLite connection was closed were being leaked (it was not clear from his e-mail whether this was a new bug with 3.5, or just that the quantity of resources leaked was greater in 3.5). This test build included a workaround for it (presumably he saved the connection instead of creating a new connection every time it updates the RSS feeds, but he didn't say).&lt;br /&gt;&lt;br /&gt;This seemed to work well. After installing it, I immediately noticed that it was not hemorrhaging memory like it did before (previously it was leaking about 25 megs each time the RSS feeds were updated, which was now gone). Rather, after a couple of days of collecting data, I concluded that it was now only leaking 1-2 megs each update (about 10 megs/hour).&lt;br /&gt;&lt;br /&gt;It's not clear yet whether this is true leakage (which would suggest that one leak was plugged but another remains) or that this is a side-effect of the workaround. It's conceivable that Firefox might delay freeing SQLite resources as long as a connection is in use; if he's indeed keeping an SQLite connection open the whole time, we could imagine that this "leak" is not a leak (lack of resource reclamation) so much as a deferral of resource reclamation. If this is the case, this should go away after Firefox fixes the SQLite connection leak and he goes back to creating a new connection on every update.&lt;br /&gt;&lt;br /&gt;We'll see.&lt;br /&gt;&lt;br /&gt;Incidentally, version 4.1 of Feed Sidebar was released today; this is the version I tried a test build of. After I've had more time to collect data I'll have to see if it's leaking the same amount as the test build, or if there have been further modifications.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8834456886510824613?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8834456886510824613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8834456886510824613' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8834456886510824613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8834456886510824613'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/07/that-memory-leak.html' title='&amp; That Memory Leak'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-8424970287532127990</id><published>2009-07-24T12:43:00.000-07:00</published><updated>2009-07-24T12:51:28.312-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>Useful Fact of the Day</title><content type='html'>As of a few versions, you can no longer get the nice graphical Visual Studio profiler in anything less than the most expensive Team Suite edition of Visual Studio. For most people (namely, those that don't have 6 grand to spend to get a profiler), this isn't really an option.&lt;br /&gt;&lt;br /&gt;Fortunately, Microsoft has been kind enough to release a command-line version of the Visual Studio 2008 profiler &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=fd02c7d6-5306-41f2-a1be-b7dcb74c9c0b&amp;amp;displaylang=en"&gt;for free&lt;/a&gt;. If you need a profiler, get it. Fortunately for me, I got Visual Studio 2005 and 2008 Team Suites for free through my school via Microsoft Developer Network Academic Alliance; unfortunately, I won't be able to do that with Visual Studio 2010, so hopefully they'll make the 2010 profiler available that way as well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8424970287532127990?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8424970287532127990/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8424970287532127990' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8424970287532127990'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8424970287532127990'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/07/useful-fact-of-day.html' title='Useful Fact of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-8970948387244959657</id><published>2009-07-23T19:08:00.000-07:00</published><updated>2009-07-23T19:15:09.378-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><title type='text'>RIP E Terra Blog</title><content type='html'>As you can see, I've removed the link and RSS feed for the &lt;a href="http://eterragame.spaces.live.com/default.aspx"&gt;E Terra blog&lt;/a&gt; from the sidebar. After several years of no real content and over a year since the last post (that's even worse than this blog!), I'm finally putting it out of its misery. If I'd been a prolific writer on the development of E Terra there might have been a purpose to a separate blog, but I sure haven't been, once the class I had to create it for ended. If I have anything to say about E Terra or game programming in the future, I'll just put it here, instead.&lt;br /&gt;&lt;br /&gt;By the way, a few semesters ago (after the class I wrote E Terra for) I got a very nice book: &lt;a href="http://www.amazon.com/Game-Engine-Design-Second-Interactive/dp/0122290631/ref=sr_1_1?ie=UTF8&amp;amp;qid=1248383882&amp;amp;sr=8-1"&gt;3D Game Engine Design&lt;/a&gt; (second edition). It's largely about graphics engines, though it does have occasional other topics (e.g. that's where I learned to write a good collision detection system for E Terra). What's really nice about this book is that it's not limited to theory; while it does explain the theory behind things, it also shows how to bring everything together into a working system. Most (useless) textbooks, in contrast, simply explain the theory and (if you're lucky) give you pseudocode for each separate concept, with no advice on how to integrate everything into a complete system. If you're interested in game programming, this is by far the best book I know of (I originally found it looking through the book shelves of my graphics teacher).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8970948387244959657?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8970948387244959657/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8970948387244959657' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8970948387244959657'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8970948387244959657'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/07/rip-e-terra-blog.html' title='RIP E Terra Blog'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-1832527288848287306</id><published>2009-07-15T17:51:00.000-07:00</published><updated>2009-07-15T17:57:43.731-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>&amp; Detexify</title><content type='html'>So, somebody just linked me to &lt;a href="http://detexify.kirelabs.org/classify.html"&gt;Detexify&lt;/a&gt;, a very neat little program that reads your "handwriting" and tries to find the &lt;a href="http://en.wikipedia.org/wiki/TeX"&gt;TeX&lt;/a&gt; special character that you just wrote.&lt;br /&gt;&lt;br /&gt;Now, personally I don't have much use for such a thing, as I don't use TeX. However, it happens to be open source, which means that if I can muster the energy I'm going to try it with the set of Chinese characters and see how well it can do identifying those. If it can do that decently I have some much less theoretical uses for it...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-1832527288848287306?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/1832527288848287306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=1832527288848287306' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1832527288848287306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1832527288848287306'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/07/detexify.html' title='&amp; Detexify'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-533681189247307009</id><published>2009-07-15T15:51:00.000-07:00</published><updated>2009-07-15T15:52:55.037-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linguistics'/><title type='text'>&amp; the Genitive</title><content type='html'>Last in the series of core cases (the four cases almost universal among languages that use &lt;a href="http://en.wikipedia.org/wiki/Grammatical_case"&gt;grammatical case&lt;/a&gt;) is the genitive (the nominative/absolutive and accusative/ergative are described &lt;a href="http://qstuff.blogspot.com/2008/06/cases-ergative-accusative.html"&gt;here&lt;/a&gt;, and the dative &lt;a href="http://qstuff.blogspot.com/2009/05/dative.html"&gt;here&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;Genitive Relation&lt;/span&gt;&lt;br /&gt;The &lt;a href="http://en.wikipedia.org/wiki/Genitive"&gt;genitive relation&lt;/a&gt; consists of a noun phrase (the minimum noun phrase in most languages being a single noun) that modifies another noun phrase. As described by grammar books, a genitive phrase is a noun phrase that specifies or describes another noun phrase, with the result being that the genitive phrase helps to answer the question "which?" with regard to the modified noun phrase; e.g. "&lt;span style="font-style: italic;"&gt;the girl next door's&lt;/span&gt; dog" (genitive in italic) answers "which dog?", "music of &lt;span style="font-style: italic;"&gt;Starcraft&lt;/span&gt;" answers "which music?", etc.&lt;br /&gt;&lt;br /&gt;As it essentially contains all manner of modifying phrases, clearly the genitive is an extremely broad relation, and there are quite a few more-specific relations that fall under the umbrella of "genitive". A semi-exhaustive listing of the various types of relations the genitive can express:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Physical possession: "&lt;span style="font-style: italic;"&gt;my &lt;/span&gt;computer"&lt;/li&gt;&lt;li&gt;Abstract possession: "&lt;span style="font-style: italic;"&gt;your &lt;/span&gt;happiness"&lt;/li&gt;&lt;li&gt;Relational: "&lt;span style="font-style: italic;"&gt;his &lt;/span&gt;wife"&lt;/li&gt;&lt;li&gt;Compositional: "bottle &lt;span style="font-style: italic;"&gt;of water&lt;/span&gt;", "box &lt;span style="font-style: italic;"&gt;of nails&lt;/span&gt;"&lt;/li&gt;&lt;li&gt;Quantitative: "half &lt;span style="font-style: italic;"&gt;of them&lt;/span&gt;"&lt;/li&gt;&lt;li&gt;Subjective: "&lt;span style="font-style: italic;"&gt;her &lt;/span&gt;snoring"&lt;/li&gt;&lt;li&gt;Objective: "&lt;span style="font-style: italic;"&gt;its&lt;/span&gt; destruction"&lt;/li&gt;&lt;li&gt;Purpose: "sledgehammer &lt;span style="font-style: italic;"&gt;of castration&lt;/span&gt;"&lt;/li&gt;&lt;li&gt;Location: "citizens &lt;span style="font-style: italic;"&gt;of America&lt;/span&gt;"&lt;/li&gt;&lt;li&gt;Origin: "Kazuhiro Sasaki &lt;span style="font-style: italic;"&gt;of Japan&lt;/span&gt;" (for those who don't know, he's a Japanese baseball player that was recruited to play professionally in America)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Affiliation: "&lt;span style="font-style: italic;"&gt;Apple&lt;/span&gt;'s Steve Jobs"&lt;/li&gt;&lt;li&gt;Attributive: "thing &lt;span style="font-style: italic;"&gt;of beauty&lt;/span&gt;"&lt;/li&gt;&lt;li&gt;Topical: "&lt;span style="font-style: italic;"&gt;Of Mice and Men&lt;/span&gt;"&lt;/li&gt;&lt;li&gt;Appositional/classifying: "&lt;span style="font-style: italic;"&gt;President &lt;/span&gt;Obama"&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;It's likely that all languages can represent all genitive relations, though the methods used in languages differ, and a single language may have multiple mechanisms that may or may not overlap. A genitive case (or multiple cases that each represent more constrained relations) is one option to represent the genitive, but a language need not have an actual case, nor are case(s) and non-case methods mutually exclusive. Japanese, for example, does not have a genitive case, while Latin (and many other Indo-European languages) has both genitive case and a variety of prepositions that allow expression of specific relations.&lt;br /&gt;&lt;br /&gt;One very good reason for a language to have more than a single mechanism of representing the genitive is that any single such mechanism would necessarily be ambiguous. Take, for example, the English phrase "betrayal &lt;span style="font-style: italic;"&gt;of Illidan&lt;/span&gt;"; with this phrase it is unclear whether the genitive is subjective or objective - that is, whether Illidan is the betrayer or the one betrayed. Other such examples can be invented based on other uses of the genitive.&lt;br /&gt;&lt;br /&gt;Of course it's not all bad; if there were no ambiguity in language, puns would be impossible. One real-life example of genitive ambiguity comes from IRC. jfroy says 'Snow Leopard meeting' in the sense of 'meeting about [Apple] Snow Leopard', to which I reply, interpreting that as 'meeting &lt;span style="font-style: italic;"&gt;with&lt;/span&gt; a snow leopard':&lt;br /&gt;&amp;lt;@jfroy&gt; Snow Leopard meeting over. Ow.&lt;br /&gt;&amp;lt;enma_hinobara&gt;Next time don't poke it&lt;br /&gt;&amp;lt;enma_hinobara&gt;It's not Kaity&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;The Genitive in English&lt;/span&gt;&lt;br /&gt;It's arguable whether English still has a genitive case; if it does, it only exists for (some) pronouns, where it indicates a purely possessive relation (which is why it might better be called the possessive case). It does, however, have three different mechanisms for expressing genitive relations in general - the periphrastic genitive, the analytic/agglutinative genitive (both are my own terms, so don't expect to find them in a dictionary), and the possessive.&lt;br /&gt;&lt;br /&gt;The periphrastic genitive renders the genitive phrase as a prepositional phrase with the preposition 'of', e.g "fog of war". This is the "true" genitive in English, in that it is the mechanism that can express nearly every possible genitive phrase (although some phrases may sound better using one of the other mechanisms), while the others are much more restricted in use.&lt;br /&gt;&lt;br /&gt;The analytic/agglutinative genitive renders the genitive relation purely by shoving two (or more) nouns together, e.g. "milk carton" (compare to "carton of milk"), "wood chips" ("chips of wood"), etc. I call it the analytic genitive because the genitive relation is expressed purely analytically - through word order, rather than word form. I call it the agglutinative genitive because in more synthetic relatives of English, such as German or Old English, the modifying word(s) would be agglutinated with the modified word to form a single large word (this can sometimes produce very long compound words); for example, "girl next door" would be "Nachbarmädchen" in German (literally "neighborgirl"). In English, this type of genitive is restricted to certain types of relations, and is especially used for classification.&lt;br /&gt;&lt;br /&gt;Finally, English has a special means of expressing possessive relations, a subset of genitive relations (it's unclear exactly how this form originated; some argue that it's an evolution of the genitive case, while others are more skeptical of that conclusion). Note here that English has a rather broad concept of possession, and as such the possessive can be used with some relations that aren't strictly possessive in nature.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;The Genitive in Latin&lt;/span&gt;&lt;br /&gt;As a relative of English, the genitive in Latin is much the same, in that genitive relations can be expressed via prepositional phrases (which are substantially similar to their English equivalents) or analytically; however, Latin also has an actual genitive case (a result of which is that it does not need a possessive structure as English does), which is used very commonly. A few examples of the genitive case in Latin:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"agricolae [farmer, genitive] filia [daughter, nominative]": "farmer's daughter"&lt;/li&gt;&lt;li&gt;"horum [these, genitive] omnium [all, genitive]": "of all these/of all of these"&lt;/li&gt;&lt;li&gt;"vir [man, nominative] magnae [great, genitive] virtutis [courage, genitive]": "man of great courage"&lt;/li&gt;&lt;li&gt;"fossa [ditch, nominative] decem [10] pedum [foot, genitive]": "ditch of ten feet/ten-foot ditch"&lt;/li&gt;&lt;li&gt;"Rex [king, nominative] belli [war, genitive] cupidus [desirous, nominative] est [is]": "The king is desirous of war"&lt;/li&gt;&lt;/ul&gt;&lt;span style="font-size:130%;"&gt;The Genitive in Japanese&lt;/span&gt;&lt;br /&gt;Finally, As Japanese does not have true case, like English it uses non-case-based structures for constructing the genitive. Japanese has two genitive-marking particles - 'no' and 'na', which differ only in whether the genitive phrase is abstract (e.g. 'baka' - 'stupidity') or concrete (e.g. 'shakunetsu' - 'scorching heat') - used in the periphrastic genitive, as well as the agglutinative/analytic genitive (the genitive may or may not actually be agglutinated). However, Japanese also shows off several uses of the genitive that English and Latin do not.&lt;br /&gt;&lt;br /&gt;Consider the rough definition of the genitive - something which specifies or defines a noun phrase; where have we heard this definition before? Well, for one, it's the definition of adjectives. In fact, a language can get by just fine with almost no true adjectives (e.g. the kind we have in English), instead opting to use one or more of the three alternate methods I talked about &lt;a href="http://qstuff.blogspot.com/2008/01/adjective-strategies.html"&gt;previously&lt;/a&gt;. One of these methods is to use the genitive with descriptive nouns, a method that is used extensively in Japanese and Caia (in fact, it's the primary method in Caia). A couple example from previously used words would be "baka na inu": "stupid dog" (literally "dog of/with stupidity") and"shakunetsu no koi": "scorching love" (literally "love of scorching heat").&lt;br /&gt;&lt;br /&gt;The other structure this definition matches is &lt;a href="http://en.wikipedia.org/wiki/Apposition"&gt;apposition&lt;/a&gt;; that is, a restatement of something previously said for the purpose of definition or clarification, such as the italicized part in "Julius, &lt;span style="font-style: italic;"&gt;son of Ambrose&lt;/span&gt;". In a previous post on the &lt;a href="http://qstuff.blogspot.com/2007/06/predicative.html"&gt;predicative&lt;/a&gt;, I explained that in Indo-European languages such phrases are in the same case as the phrase they restate, but that we could imagine other reasonable ways of expressing them. In Japanese such phrases may be expressed either by the analytic genitive (e.g. "kemono [beast] no sousha [player, generally of an instrument] Erin": "Erin the beast player") or the periphrastic genitive (e.g. "Hamelin no violin hiki [player]": "Hamelin the violinist" - literally "violinist of Hamelin").&lt;br /&gt;&lt;br /&gt;Finally, some languages, such as Japanese and Caia, allow other relational phrases to be put into the genitive, where the genitive particle indicates the modification of a noun phrase, and the other relational particle specifies the precise relation of the genitive phrase (you might say the genitive particle applies top-down, while the other relational particle applies bottom-up). Some examples of this in Japanese:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;"ano [that] group to [with] no kankei [relationship]": "relationship with that group" (literally "relationship of with that group")&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"ano kaisha [company] to no keiyaku [contract]": "contract with that company"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"Asia kara [from] no ryuugakusei [exchange student]": "exchange student from Asia" (literally "exchange student of from Asia")&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"Hokkaido kara no omiyage [souvenir]": "souvenir from Hokkaido"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"America ye [towards/to] no monkowohiraku [opening the door; this is rendered as a noun in this phrase, not a verb, in this example]": "opening the door to America" (literally "opening the door of to America")&lt;br /&gt;&lt;/li&gt;&lt;li&gt;"anata [you] ye no tegami [letter]": "letter to/for you"&lt;/li&gt;&lt;/ul&gt;&lt;!-- ni no? http://www.csse.monash.edu.au/~jwb/cgi-bin/wwwjdic.cgi?9O5073794  de no ? http://www.csse.monash.edu.au/~jwb/cgi-bin/wwwjdic.cgi?9O183306 http://www.csse.monash.edu.au/~jwb/cgi-bin/wwwjdic.cgi?9O1569243 http://www.csse.monash.edu.au/~jwb/cgi-bin/wwwjdic.cgi?9O1838658 --&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-533681189247307009?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/533681189247307009/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=533681189247307009' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/533681189247307009'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/533681189247307009'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/07/genitive.html' title='&amp; the Genitive'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6367094699216679941</id><published>2009-06-05T13:19:00.000-07:00</published><updated>2009-06-05T13:22:32.981-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><category scheme='http://www.blogger.com/atom/ns#' term='anime'/><title type='text'>&amp; the Real World</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://farm2.static.flickr.com/1290/847642178_7d47e09728.jpg"&gt;&lt;img style="cursor: pointer; width: 500px; height: 330px;" src="http://farm2.static.flickr.com/1290/847642178_7d47e09728.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Martial arts in a skirt, eh? I thought that kind of thing only happened in anime.&lt;br /&gt;&lt;br /&gt;(found via &lt;a href="http://www.darkroastedblend.com/2007/01/anti-us-north-korean-posters.html"&gt;http://www.darkroastedblend.com/2007/01/anti-us-north-korean-posters.html&lt;/a&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6367094699216679941?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6367094699216679941/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6367094699216679941' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6367094699216679941'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6367094699216679941'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/06/real-world.html' title='&amp; the Real World'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1290/847642178_7d47e09728_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-3890853143883471331</id><published>2009-05-27T12:53:00.000-07:00</published><updated>2009-05-27T12:54:40.475-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linguistics'/><title type='text'>The Dative</title><content type='html'>The &lt;a href="http://en.wikipedia.org/wiki/Dative_case"&gt;dative&lt;/a&gt;, or indirect object, is one of the four core cases - those cases that are almost universal in languages that have case - along with nominative/absolutive, accusative/ergative, and the genitive.&lt;br /&gt;&lt;br /&gt;While the details vary by language, the general concept for the dative is a goal or direction of an action (especially with regard to transfer or movement), or the one perceiving an action. In the study of &lt;a href="http://en.wikipedia.org/wiki/Thematic_relation"&gt;grammatical role&lt;/a&gt;, the dative roughly corresponds to the role of goal (although it may have additional uses in a given language). While English has pretty much lost its case system, the logical dative remains, usually expressed with the prepositions 'to' or 'for'.&lt;br /&gt;&lt;br /&gt;Some examples of the various uses in several languages from Wikipedia and other sources (note that I'm mainly covering the most common uses, not ones that are specific to certain languages):&lt;br /&gt;&lt;br /&gt;Goal of Transfer:&lt;br /&gt;Latin: "Regina &lt;span style="font-style: italic;"&gt;puellae&lt;/span&gt; pecuniam dat" ("The queen gives money &lt;span style="font-style: italic;"&gt;to the girl&lt;/span&gt;")&lt;br /&gt;Japanese: "&lt;span style="font-style: italic;"&gt;Kodomo ni&lt;/span&gt; yaru" ("Give &lt;span style="font-style: italic;"&gt;to the child&lt;/span&gt;")&lt;br /&gt;&lt;br /&gt;Goal of Movement:&lt;br /&gt;Japanese: "Ano hito wa &lt;span style="font-style: italic;"&gt;gakkou ni&lt;/span&gt; haitta" ("That man has gone &lt;span style="font-style: italic;"&gt;to the school&lt;/span&gt;")&lt;br /&gt;&lt;br /&gt;Goal of Intent or Benefit&lt;br /&gt;Latin: "&lt;span style="font-style: italic;"&gt;Auxilio&lt;/span&gt; vocare" ("I call &lt;span style="font-style: italic;"&gt;for help&lt;/span&gt;")&lt;br /&gt;Latin: "&lt;span style="font-style: italic;"&gt;P&lt;/span&gt;&lt;i&gt;uellae ornamento&lt;/i&gt; est" ("It is &lt;span style="font-style: italic;"&gt;for the girl's decoration&lt;/span&gt;")&lt;br /&gt;Latin: &lt;i&gt;Graecis&lt;/i&gt; agros colere ("To till fields &lt;span style="font-style: italic;"&gt;for the Greeks&lt;/span&gt;")&lt;br /&gt;Greek: "&lt;span style="font-style: italic;"&gt;τῷ βασιλεῖ&lt;/span&gt; μάχομαι" ("I fight &lt;span style="font-style: italic;"&gt;for the king&lt;/span&gt;")&lt;br /&gt;Greek: "πᾶς ἀνὴρ &lt;span style="font-style: italic;"&gt;αὑτῷ&lt;/span&gt; πονεῖ" ("Every man toils &lt;span style="font-style: italic;"&gt;for himself&lt;/span&gt;")&lt;br /&gt;&lt;br /&gt;Goal of Experience:&lt;br /&gt;Latin: "Vir bonus &lt;span style="font-style: italic;"&gt;mihi&lt;/span&gt; videtur' 'the man seems good &lt;span style="font-style: italic;"&gt;to me&lt;/span&gt;"&lt;br /&gt;Latin: "Quid &lt;span style="font-style: italic;"&gt;mihi&lt;/span&gt; Celsus agit?" ("What is Celsus doing [&lt;span style="font-style: italic;"&gt;that I am interested in&lt;/span&gt;]?")&lt;br /&gt;&lt;br /&gt;One of the more peculiar uses (at least for English speakers, as I don't think English has anything like it), is the dative of possession. This renders phrases of possession as phrases of existence with the possessor in the dative. The logical basis of this usage is that in terms of grammatical role, in phrases of possession the possessor is technically classified as the goal.&lt;br /&gt;&lt;br /&gt;Some examples:&lt;br /&gt;Latin: "&lt;span style="font-style: italic;"&gt;A&lt;/span&gt;&lt;i&gt;ngelis&lt;/i&gt; alae sunt" (literally "&lt;span style="font-style: italic;"&gt;For angels&lt;/span&gt; there are wings"; freely "Angels have wings")&lt;br /&gt;Greek: "&lt;span style="font-style: italic;"&gt;ἄλλοις&lt;/span&gt; μὲν γὰρ χρήματα ἐστι πολλὰ καὶ ἵπποι, &lt;span style="font-style: italic;"&gt;ἡμῖν&lt;/span&gt; δὲ ξύμμαχοι ἀγαθοί" (literally "&lt;span style="font-style: italic;"&gt;For others&lt;/span&gt; there is a lot of money and ships and horses, but &lt;span style="font-style: italic;"&gt;for us&lt;/span&gt; there are good allies")&lt;br /&gt;Japanese: "&lt;span style="font-style: italic;"&gt;Watashi ni&lt;/span&gt; tsuno ga nai" (literally "&lt;span style="font-style: italic;"&gt;For me&lt;/span&gt; there aren't horns")&lt;br /&gt;Tsez: "&lt;span style="font-style: italic;"&gt;Кидбехъор&lt;/span&gt; кIетIу зовси" (literally "&lt;span style="font-style: italic;"&gt;For the girl&lt;/span&gt; there was a cat")&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-3890853143883471331?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/3890853143883471331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=3890853143883471331' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3890853143883471331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3890853143883471331'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/05/dative.html' title='The Dative'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-3992883724447353182</id><published>2009-05-25T21:08:00.000-07:00</published><updated>2009-05-25T21:15:52.731-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='other'/><title type='text'>Random Fact of the Day</title><content type='html'>I just learned that some lizards (e.g. Gila Monsters, Komodo Dragons) &lt;a href="http://en.wikipedia.org/wiki/Komodo_dragon#Venom"&gt;are venomous&lt;/a&gt;.&lt;br /&gt;&lt;blockquote&gt;MRI scans of a preserved skull showed the presence of two poison glands in the lower jaw. They extracted one of these glands from the head of a terminally ill specimen in the Singapore Zoological Gardens, and found that it secreted a venom containing several different toxic proteins. The known functions of these proteins include inhibition of blood clotting, lowering of blood pressure, muscle paralysis, and the induction of hypothermia, leading to shock and loss of consciousness in envenomated prey.&lt;/blockquote&gt;I'd always heard what had been previously believed - that they merely had toxic bacteria in their mouths that was transferred in bites.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-3992883724447353182?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/3992883724447353182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=3992883724447353182' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3992883724447353182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3992883724447353182'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/05/random-fact-of-day.html' title='Random Fact of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-4233328846140865465</id><published>2009-05-15T12:38:00.000-07:00</published><updated>2009-05-15T13:25:06.386-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='linguistics'/><title type='text'>Basic Word Order</title><content type='html'>Obviously, English typically has has the word order subject-verb[-(direct) object] (or SVO, for short). This can be altered in specific situations due to WH-movement (e.g. OSV in "What would you like?") and other structures, but SVO is the normal word order. &lt;br /&gt;&lt;br /&gt;However, this isn't the only possible word order. Basic combination math tells us that there are six possible orders: SVO, SOV (e.g. Japanese, Korean, Latin, and Proto-Indo-European), VSO (e.g. Hebrew, Trique, and Caia), VOS, OSV, OVS; these are, however, not all equally likely. &lt;br /&gt;&lt;br /&gt;Two rules have been developed which govern the prominence of different word orders. First, there's a tendency for the subject to precede the (direct) object. This is known as subject salience. There have been various theories on the exact reason for this; the general idea is that it's more natural for the subject to precede the object because they subject is typically the source of an action, and thus precedes the object in both cause and effect and chronological order.&lt;br /&gt;&lt;br /&gt;The other is that there is a tendency for the object to sit next to the verb (on either side). Linguistics thus far has developed the notion that the object and the verb logically form a structure called the predicate, which stands apart from the subject (i.e. a clause is typically defined as a subject + a predicate). I haven't investigated the full depth of why this has been decided, so I couldn't really give more detail than that (though it's noteworthy that this idea is consistent with &lt;a href="http://qstuff.blogspot.com/2009/04/random-late-night-thought.html"&gt;my hypothesis&lt;/a&gt; that language began as commands - the command forms the predicate, and the subject was added in later).&lt;br /&gt;&lt;br /&gt;Thus, we have four classes of word order: those that meet both conditions, those that meet one or the other, and those that meet neither. In agreement with theory, SVO and SOV are by far the most common among languages, at 42% and 45%, respectively. On the distant second tier is VSO, which places the subject between verb and object, occurring with 9% frequency. On the again distant third tier are VOS, and OVS, each placing the object before the subject; these occur with 3% and 1% frequency, respectively. At the bottom is OSV, which violates both rules, and was not seen in any language in this survey of 402 languages.&lt;br /&gt;&lt;br /&gt;Clearly the subject salience rule dominates in significance, as orders where object precedes subject are very rare (3% or less); although it's also true that languages where the object is not next to the verb are uncommon (9% or less).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-4233328846140865465?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/4233328846140865465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=4233328846140865465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4233328846140865465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4233328846140865465'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/05/basic-word-order.html' title='Basic Word Order'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-8274591948914164518</id><published>2009-05-06T22:10:00.000-07:00</published><updated>2009-05-06T22:18:38.315-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='anime'/><title type='text'>&amp; Spring 2009 Anime Music</title><content type='html'>I've been meaning to write a post about the anime series I'm watching this season (though some I still haven't decided if I'm gonna watch all of yet), but thus far (up to and including now) I've been too lazy to actually do it.&lt;br /&gt;&lt;br /&gt;Instead, I'll do something that's substantially less work for me: post some of the theme songs of series I'm watching with (very) brief comments.&lt;br /&gt;&lt;br /&gt;The Asura Cryin' ending theme is really the one that made me decide to do this post. Which is to say I'm fond of it.&lt;br /&gt;&lt;object width="450" height="266"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/9KD_eEYi3GA&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/9KD_eEYi3GA&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="450" height="266"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;The music within the series also didn't seem too bad. I haven't heard enough to decide whether I think it's good, it's certainly superior to the typical mediocre anime music.&lt;br /&gt;&lt;br /&gt;The opening isn't as good as the ending, but not bad, especially the first 20 seconds or so.&lt;br /&gt;&lt;object width="450" height="266"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/o1Of96vZDls&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/o1Of96vZDls&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="450" height="266"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;As I watched the Pandora Hearts opening theme, the short violin segment reminded me of Yuki Kajiura, one of my favorite composers, who is known especially for very pretty violin pieces. A quick look on Anime News Network confirmed that the series was indeed done by her. I wouldn't say the opening is her best work, but it's certainly not bad.&lt;br /&gt;&lt;object width="450" height="355"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/Zm9fhJHoWo8&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/Zm9fhJHoWo8&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="450" height="335"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;So that should mean the music for the series will be pretty good.&lt;br /&gt;&lt;br /&gt;The ending isn't as good as the opening, but from a quick glance at the credits I don't think it was done by her (it's fairly common for the openings and/or endings to be done by different composers than the series music - often real bands). It also isn't bad.&lt;br /&gt;&lt;object width="450" height="355"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/R1osPH8iqQ8&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/R1osPH8iqQ8&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="450" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;K-ON! is a quirky series. It's amusing, but excessively cute. From what I've seen so far, the music is very mediocre, though the opening and ending aren't quite so much, though for different reasons.&lt;br /&gt;&lt;object width="450" height="355"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/kviqEdhL3kE&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/kviqEdhL3kE&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="450" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;About all I have to say about that is that I don't think I'll be listening to that opening apart from showing it to people with hangovers.&lt;br /&gt;&lt;br /&gt;The ending is similarly loud, but substantially better; palatable, and even a bit catchy. I do really like the animation that goes along with the ending theme - parts of it are quite artistic, and look very sharp (such as the black and white ensemble).&lt;br /&gt;&lt;object width="450" height="355"&gt;&lt;param name="movie" value="http://www.youtube-nocookie.com/v/GUKwH81csts&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube-nocookie.com/v/GUKwH81csts&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="450" height="355"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8274591948914164518?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8274591948914164518/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8274591948914164518' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8274591948914164518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8274591948914164518'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/05/spring-2009-anime-music.html' title='&amp; Spring 2009 Anime Music'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-6169871617285298214</id><published>2009-04-26T10:44:00.000-07:00</published><updated>2009-04-26T10:46:19.253-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='linguistics'/><title type='text'>Empathy Hierarchy and Other Ungodly Things</title><content type='html'>A ways back I wrote a &lt;a href="http://qstuff.blogspot.com/2008/04/random-linguistic-fact-of-day.html"&gt;post&lt;/a&gt; about empathy (also called animacy or agency) &lt;a href="http://en.wikipedia.org/wiki/Animacy_hierarchy"&gt;hierarchies&lt;/a&gt; and how the empathy hierarchy in Spanish and other romance languages worked, explaining a peculiarity of their grammar that had haunted me since high school Spanish. Unfortunately, I was excited at the time I was writing, and didn't explain it near as clearly as I should have.&lt;br /&gt;&lt;br /&gt;Anyway, to briefly recap, empathy hierarchy is a system of classifying entities (e.g. nouns) according to the level of empathy the speaker feels towards them. While the number and composition of levels vary by language, the general trends are 1st person &gt;= 2nd person &gt;= 3rd person, animate &gt;= inanimate, definite &gt;= indefinite (e.g. "those people" &gt;= "some people"). In Spanish there were three levels with regard to verb agreement: 1st person ("[yo] juego" - "I play") &gt; 2nd person familiar ("[tú] juegas") &gt; 2nd person formal ("usted juega") + 3rd person ("[él] juega"); this makes logical sense because you would have more empathy towards those you would address with the 2nd person familiar (e.g. your friends and family) than those you would address with the formal 2nd person (e.g. people you meet on the street). One of the most common things governed by empathy hierarchy is verb agreement, which is exactly what is seen in Spanish in the above examples.&lt;br /&gt;&lt;br /&gt;One of the languages (actually a family of languages) I'm creating for one of my stories turns the concept of empathy hierarchy completely upside-down. In these languages, verbs agree with the subject, direct object [if any], and indirect object [if any] (this is as complicated as it sounds, though some real "&lt;a href="http://en.wikipedia.org/wiki/Polypersonal_agreement"&gt;polypersonal&lt;/a&gt;" languages actually do have verbs that agree with all three of those). As the subject, direct object, and indirect object are not marked for case and word order is free, verb agreement is really the only way to tell who's doing what in a sentence; for example, you could have something like "Dog bone boy gaveheitit" or "Bone boy dog gaveheitit", which would mean more or less the same thing, as word order isn't important in this respect (word order indicates more subtle things, such as what is emphasized in a sentence).&lt;br /&gt;&lt;br /&gt;However, instead of relying on animacy or empathy to create this agreement system (animacy and/or empathy being pretty much universal in natural languages, as far as I know), these languages use rank. Specifically, a seven-tiered hierarchy with levels I label -3 (lowest) to +3 (highest). For humans, rank reflects social status relative to the speaker. Rank 0 is reserved for the first person, ranks below 0 represent those below the social status of the speaker, and ranks above 0 above the speaker, with the degree of difference indicated by the rank (rank x + 1 &gt; rank x); e.g. use of rank 2 by the speaker to refer to someone would mean that that person has a social status substantially higher than that of the speaker. For nonhumans (animals and inanimate objects) rank is based on respect for that thing - positive and/or honorable things would have high rank, negative or dishonorable things would have low rank; in this way rank resembles more arbitrary noun class systems.&lt;br /&gt;&lt;br /&gt;Now, depending on how deeply you thought about what I just said, you may or may not already be scared of this idea; so let me illustrate. Suppose you have two coworkers at a job talking to each other (thus they'd be of the same social status). As it's customary to show some respect to those of the same rank as you in East Asian cultures (these languages are loosely based on Japanese, with a bunch of fun stuff thrown in), both would refer to each other ("you" in English) with the +1 level. However, as this system does not distinguish between 2nd and 3rd person, if one of them uses the +1 level for something, it could just as easily refer to some third co-worker who wasn't a part of the conversation (a 3rd person, no pun intended). Or it could simply refer to some inanimate object that just happens to be at the +1 rank.&lt;br /&gt;&lt;br /&gt;But that's easy stuff. Now imagine a person writing to a politician. If this was just an average person, they might use rank +2 to refer to the politician ("you", in English), given the significant difference in social status. The politician would then use rank -2 to refer to the person (or -1, if the politician wanted to be polite), which would also be written "you" in English. Now suppose they were talking about the king. The lay person would probably refer to the king with +3 rank; the politician, however, would use a lower rank (+1 or +2), as their own social status is greater. Of course, any of these (-2, -1, +1, +2, +3) could simply be referring to an inanimate object, instead.&lt;br /&gt;&lt;br /&gt;Worse yet, the innate rank of an animal or inanimate object could be modified based on the rank of a possessor; that is, if the possessor of an object has a significantly different rank than the speaker, the rank of the thing possessed might be elevated or lowered to reflect the possessor.&lt;br /&gt;Suppose that dog' has an innate rank of +1. In the previous scenario, the person might then use rank +1 to refer to his dog, +2 to refer to the politician's dog, and +2 or +3 to refer to the king's dog. The politician, on the other hand, might refer to his own dog as +1, the person's dog as -1, and the king's dog as +2.&lt;br /&gt;&lt;br /&gt;And as one last nail in the coffin of sanity is a concept I call the heterogeneous plural. That is, a plural that comprises members of significantly different rank. In this case, the rank of the group as a whole would be the rank of the highest-ranking member. So if the person writing a politician referred to level +3, he could be referring the the king, the king and the politician together, the king's dog, or something else entirely.&lt;br /&gt;&lt;br /&gt;That's me: raping your mind since 1983.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-6169871617285298214?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/6169871617285298214/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=6169871617285298214' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6169871617285298214'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/6169871617285298214'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/04/empathy-hierarchy-and-other-ungodly.html' title='Empathy Hierarchy and Other Ungodly Things'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-8545246568888801697</id><published>2009-04-11T22:12:00.000-07:00</published><updated>2009-04-11T22:19:05.773-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><title type='text'>Moving On Up</title><content type='html'>I'd heard all of this from him directly, but I just ran across this post on the ZDNet Security blog - &lt;a href="http://blogs.zdnet.com/security/?p=3000"&gt;Microsoft adds 'Skywing' to Windows defense team&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Incidentally, Miller is the arch-nemesis I &lt;a href="http://qstuff.blogspot.com/2007/05/i-didnt-actually-win.html"&gt;mentioned earlier&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8545246568888801697?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8545246568888801697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8545246568888801697' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8545246568888801697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8545246568888801697'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/04/moving-on-up.html' title='Moving On Up'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-1819879318967230238</id><published>2009-04-10T11:15:00.000-07:00</published><updated>2009-04-10T11:16:18.294-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='linguistics'/><title type='text'>Random Late-Night Thought</title><content type='html'>For a while I've been aware of a particular piece of linguistic evidence - namely, that cross-linguistically it is common for the imperative (command) form of verbs to be shorter than other forms, seemingly lacking inflectional affixes applied to other conjugations. For example, in Old English, the verb 'creopan' (infinitive form) is 'creope' for first person singular, 'criepth' for third person singular, but 'creop' for imperative singular. This led me to hypothesize that language might have begun as commands, and later evolved to support more general types of expressions by the addition of affixes or extra words.&lt;br /&gt;&lt;br /&gt;Think about the significance of this for a moment. One of the most frequent differences between normal sentences and imperative sentences is that the imperative usually does not have a (stated) subject, while, depending on the language, general sentences may require subjects.&lt;br /&gt;&lt;br /&gt;Now, one of the big mysteries of linguistics is how we came to have such radically different language systems as &lt;a href="http://en.wikipedia.org/wiki/Accusative_language"&gt;accusative&lt;/a&gt;, &lt;a href="http://en.wikipedia.org/wiki/Ergative%E2%80%93absolutive_language"&gt;ergative&lt;/a&gt;, and &lt;a href="http://en.wikipedia.org/wiki/Topic-prominent_language"&gt;topic-comment&lt;/a&gt;*. Yet if commands were all that was originally spoken, this provides us with a trivial answer: initially, there was only a direct object and no subject, thus that language would predate the differentiation of the three types.&lt;br /&gt;&lt;br /&gt;As the language evolved further, eventually there would be the need to add in a subject; how exactly this was handled would then determine which of the three paths was taken. Accusative languages would place the subject in a separate case (nominative) from the direct object (accusative case). Ergative languages would &lt;a href="http://qstuff.blogspot.com/2008/06/cases-ergative-accusative.html"&gt;classify the subject&lt;/a&gt; based on whether its role is the agent (ergative case) or patient (absolutive case). Finally, topic-comment languages would place the subject (the topic) completely apart from the rest of the sentence (the comment).&lt;br /&gt;&lt;br /&gt;*Since I don't think I've talked too much about topic-comment structure, I'll briefly explain here. In topic-comment languages, a topic is stated for a sentence or set of sentences, then a number of comments are made regarding that topic. Japanese, Korean, and Chinese are like this, among others, although it's also possible to use a periphrastic form in languages like English (e.g. "As for the movie [the topic], we'll meet at 2 [the comment]").&lt;br /&gt;&lt;br /&gt;Of particular relevance, one thing the topic can be used for is the subject of the sentence, e.g. "As for him, he'll be coming later" (though true topic-comment languages usually wouldn't duplicate the subject as English does - it would be more like "As for him, will come later"); this is frequently done in Japanese and Korean, for example. Of course, the comment may have a different subject than the topic, so topic-comment languages may also be accusative or ergative (e.g. Japanese is accusative). Here I am hypothesizing that initially the subject was represented exclusively as the topic, then further evolution allowed the subject to be within the comment itself (although whether this is true is relatively unimportant to the theory that languages began as commands).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-1819879318967230238?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/1819879318967230238/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=1819879318967230238' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1819879318967230238'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1819879318967230238'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/04/random-late-night-thought.html' title='Random Late-Night Thought'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-3808037852001187987</id><published>2009-04-09T10:31:00.000-07:00</published><updated>2009-04-09T10:36:21.695-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>Curve Ball</title><content type='html'>Some surprising last-minute &lt;a href="http://torrentfreak.com/france-rejects-anti-piracy-law-090409/"&gt;good news&lt;/a&gt; from France:&lt;br /&gt;&lt;blockquote&gt;After the parliament voted in favor of the law, no one doubted that it would be approved by the senate and National Assembly as well. As expected the law was indeed ratified by the senate this morning, but to everyone’s surprise it didn’t make it through the National Assembly.&lt;br /&gt;...&lt;br /&gt;Unfortunately the law is not completely off the table. It is likely to be voted on again on April 27 according to members of UMP, one of the supporting parties. However, failing to get it passed through the National Assembly the first time is clearly a huge mistake that is almost amateurish, and public opinion is not likely to change anytime soon.&lt;/blockquote&gt;&lt;br /&gt;Which I suppose makes for a (tentative) good-triumphs-over-evil-in-the-end Hollywood ending, after what the proponents of the law &lt;a href="http://qstuff.blogspot.com/2009/04/name-that-movie.html"&gt;pulled in parliament&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-3808037852001187987?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/3808037852001187987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=3808037852001187987' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3808037852001187987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/3808037852001187987'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/04/curve-ball.html' title='Curve Ball'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-7336564296442285436</id><published>2009-04-03T13:54:00.000-07:00</published><updated>2009-04-03T15:43:30.781-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Name That Movie</title><content type='html'>See if you can recognize this one.&lt;br /&gt;&lt;br /&gt;A bill written by big business interests is proposed in French parliament. Hugely controversial, the bill is opposed by most apart from the business interests that wrote it, and it is difficult to see how it could pass (although you can never underestimate the corruption of government officials). As the deadline for the vote draws near, an intense debate lasting 42 hours straight breaks out among parliament members.&lt;br /&gt;&lt;br /&gt;Eventually, late Thursday evening, it is decided that the debate should cease and parliament members should go home for the night, and the bill would be voted on the next week. So, parliament members do exactly that. After about 98% of parliament members have left the building, the vote is called early, at nearly 11 PM on Thursday night. With 16 members remaining, the bill passes, 12 to 4.&lt;br /&gt;&lt;br /&gt;Can you name that movie?&lt;br /&gt;&lt;br /&gt;Actually you can't, because it &lt;a href="http://translate.google.com/translate?u=http%3A%2F%2Fwww.numerama.com%2Fmagazine%2F12527-La-loi-Hadopi-votee-a-la-sauvette-par-une-poignee-de-deputes.html&amp;amp;sl=fr&amp;amp;tl=en&amp;amp;hl=en&amp;amp;ie=UTF-8"&gt;actually happened&lt;/a&gt; - yesterday. This is the French Three-Strikes law, which promises to disconnect people from the internet on allegation of copyright infringement, without ever having to present evidence in court or even tell the accused what copyright they are thought to have infringed. It will also require running spyware on all computers that constantly talks to government systems and monitors activity and the state of your network.&lt;br /&gt;&lt;br /&gt;Welcome to French democracy, proving that America really isn't that bad afterall.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-7336564296442285436?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/7336564296442285436/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=7336564296442285436' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7336564296442285436'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/7336564296442285436'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/04/name-that-movie.html' title='Name That Movie'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-4394172881195441806</id><published>2009-04-01T14:50:00.000-07:00</published><updated>2009-04-01T14:52:05.493-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><title type='text'>&amp; Patents... or Lack Thereof</title><content type='html'>A ways back (might have even been a couple years), I came up with an idea for something called Anonymous Private Mail, or a-p mail, a system of e-mail which provides for much greater privacy. Rather than using an e-mail address, a-p mail identifies individuals by their public/private key pair used to encrypt the e-mails (the private part). What made the a-p mail system so novel was that it was able to route a message from sender to receiver &lt;span style="font-style: italic;"&gt;without ever knowing the keys of the sender or recipient&lt;/span&gt; (the anonymous part). Because of this, the e-mail server (or anyone monitoring it) could not even tell if two e-mails were sent by the same person or received by the same person (in contrast to normal e-mail systems, where the server always knows at least the e-mail address of the receiver).&lt;br /&gt;&lt;br /&gt;I was initially concerned about disclosing how it works, especially with regard to patenting it. This system originated in one of my stories (the universe of Starfall and Eve of Tomorrow, which I briefly &lt;a href="http://qstuff.blogspot.com/2008/01/fiction-fiction.html"&gt;mentioned previously&lt;/a&gt;) as a method allowing criminals (especially terrorists) to communicate. I was concerned that if I patented it, it would be used in the same was it was used in the story. For this reason I posted the basic description (essentially what I wrote above) on this blog and some forums, asking for comments about whether I should patent it or keep it secret forever.&lt;br /&gt;&lt;br /&gt;Eventually, a consensus opinion was reached that if I'd managed to come up with this idea, others would also be able to, so the only thing that keeping it secret would do is prevent me from potentially receiving licensing fees for the patent on it. So, after a great deal of procrastination (me being me), I finally wrote up the patent application and submitted it to the &lt;a href="http://www.uspto.gov/"&gt;US Patent and Trademark Office&lt;/a&gt; last Thursday.&lt;br /&gt;&lt;br /&gt;While not entirely unforeseeable, I was still very surprised to find two men in suits at my front door on Friday. To make a long discussion short, they explained that they were from the &lt;a href="http://www.dhs.gov/index.shtm"&gt;US Department of Homeland Security&lt;/a&gt;; they had seen my patent application, and, apparently, I wasn't the only one concerned about the possible application of the method to criminal organizations (particularly terrorism). They informed me that they'd deleted my patent application, and presented me with a federal gag order barring me from disclosing the details of the method to anyone else (including making further attempts to patent it).&lt;br /&gt;&lt;br /&gt;So, I guess I won't be patenting it afterall. Funny how all decisions become easy when you're reduced to only a single option... At least this won't impact my stories - as they weren't targeted specifically at people with great knowledge of computers, most people wouldn't have understood the thing even if I had explained how it worked in the stories.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-4394172881195441806?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/4394172881195441806/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=4394172881195441806' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4394172881195441806'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/4394172881195441806'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/04/patents-or-lack-thereof.html' title='&amp; Patents... or Lack Thereof'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-8128695530459398908</id><published>2009-03-27T17:44:00.000-07:00</published><updated>2009-03-27T18:14:46.101-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='computers'/><category scheme='http://www.blogger.com/atom/ns#' term='reallife'/><title type='text'>So Much for That</title><content type='html'>A couple weeks ago I happened to be at a certain computer store. I happened to notice that they had a sale on a GeForce 9400 GT 512 meg video card for $40 (normally $70). While I already have a sufficiently powerful video card, I'd been thinking for a while about picking up a cheap GeForce, in case I ever felt inclined to play with &lt;a href="http://en.wikipedia.org/wiki/CUDA"&gt;CUDA&lt;/a&gt; (my video card is an ATI). So, I grabbed one.&lt;br /&gt;&lt;br /&gt;After a sufficient amount of procrastination (specifically, two weeks, bringing it to the last day to return it), I figured I should see about opening it and installing it, to make sure it works. But first I decided to do a bit of research: namely, whether you can have both an ATI and nVidia card in the computer at a time. Obviously this &lt;span style="font-style: italic;"&gt;should&lt;/span&gt; work, but with the ATI and nVidia war, driver idiocy, etc., you never know.&lt;br /&gt;&lt;br /&gt;Well, it turns out that you can't - at least, not in Vista (I'm using 2008, which is based on Vista). Specifically, &lt;a href="http://www.microsoft.com/whdc/device/display/multimonVista.mspx#EMC"&gt;Vista only allows one WDDM display driver to be loaded at a time&lt;/a&gt;; this means that if you have multiple video cards, they all need to use the same video driver. While Vista still supports older XP XPDM display drivers (and &lt;a href="http://www.microsoft.com/whdc/device/display/multimonVista.mspx#EOB"&gt;allows multiple XPDM drivers to be loaded at once&lt;/a&gt;), it'll cost you - WDDM drivers are required for things such as Aero and DirectX 10; worse, you can't have one driver that's XPDM and one that's WDDM. Windows 7 is rumored to support multiple WDDM display drivers at once.&lt;br /&gt;&lt;br /&gt;And that's why I tried it while it was still returnable, and didn't open it before doing some basic research.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8128695530459398908?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8128695530459398908/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8128695530459398908' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8128695530459398908'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8128695530459398908'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/03/so-much-for-that.html' title='So Much for That'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-1066323058883211144</id><published>2009-03-26T16:16:00.000-07:00</published><updated>2009-03-26T16:26:08.217-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='bugs'/><category scheme='http://www.blogger.com/atom/ns#' term='programming'/><category scheme='http://www.blogger.com/atom/ns#' term='wtf'/><title type='text'>Die, .NET. Thanks.</title><content type='html'>So, just encountered an (extremely) evil quirk of the .NET platform in a bug.&lt;br /&gt;&lt;br /&gt;Everyone who programs .NET knows that one key difference between the two is that structs are (without ref specified) always passed by value, while classes are passed by reference. Apparently that rule is not limited to actual passing of structs, themselves; passing a "pointer" to a callback function for an instance of a struct causes a copy of the entire struct to be passed, and the callback is then called on that copy, &lt;span style="font-style: italic;"&gt;not your original instance&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;Example:&lt;br /&gt;system.FindCollisions(collisionSet.OnPossibleCollision, workingSet);&lt;br /&gt;&lt;br /&gt;In this line, FindCollisions receives a local copy of collisionSet. When it then calls that callback function, that callback operates on the local copy, &lt;span style="font-style: italic;"&gt;not on collisionSet itself&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;I'm not sure whether this is by design or whether it's a bug. While it's consistent with the policy of always passing structs by value, the fact that it's &lt;span style="font-style: italic;"&gt;so&lt;/span&gt; counter-intuitive makes me wonder if it might not be a bug.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-1066323058883211144?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/1066323058883211144/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=1066323058883211144' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1066323058883211144'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1066323058883211144'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/03/die-net-thanks.html' title='Die, .NET. Thanks.'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-1005862559398408651</id><published>2009-03-25T13:26:00.000-07:00</published><updated>2009-03-25T13:45:45.219-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>&amp; More Piracy</title><content type='html'>I haven't written about it as much on this blog as other places (instant messages, IRC, various forums, etc.), but I'm a huge opponent of both &lt;a href="http://en.wikipedia.org/wiki/Digital_rights_management"&gt;Digital Rights Management&lt;/a&gt; (also known as &lt;a href="http://en.wikipedia.org/wiki/Digital_rights_management#DRM_opposition"&gt;Content Restriction, Annulment and Protection&lt;/a&gt;) and draconian anti-piracy efforts like the &lt;a href="http://en.wikipedia.org/wiki/Recording_Industry_Association_of_America#Efforts_against_file_sharing"&gt;RIAA's law suit campaign&lt;/a&gt;. This was based on the belief that regardless of the raw numbers (e.g. total P2P downloads of something vs. actual sales), the total number of lost sales due to piracy was low enough that it was better to just eat the losses as part of the cost of doing business than to expend the effort, cost, and public good will to try and fight piracy (which wouldn't work anyway). Specifically, I was guessing that the actual losses were in the 5-15% range - that is, if there were 0 piracy, producers could sell 5-15% more of whatever they make.&lt;br /&gt;&lt;br /&gt;However, just now I came across some &lt;a href="http://2dboy.com/2008/11/13/90/"&gt;rather shocking statistics&lt;/a&gt;, complements of the makers of World of Goo (a game that shipped without DRM). According to their data collection, 82% of copies of the game played were pirated. That's higher than I expected, but that wasn't the shocking part: that the ratio of pirated copies to lost sales is about 1000:1. Crunching the numbers and rounding up a bit to err on the side of caution, this means that the actual losses of piracy are less than 0.6% of the revenue they make from legitimate sales. This is between 8 and 25 times &lt;span style="font-style: italic;"&gt;lower&lt;/span&gt; than I thought it would be.&lt;br /&gt;&lt;br /&gt;These numbers absolutely demolish the claims that&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Internet piracy seriously hurts publishers (the actual damage is negligibly small)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;That DRM does more help than harm by reducing piracy (with levels of losses that low, there isn't any &lt;span style="font-style: italic;"&gt;room&lt;/span&gt; for DRM to help, yet it's clear that it does a substantial amount of harm)&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-1005862559398408651?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/1005862559398408651/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=1005862559398408651' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1005862559398408651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1005862559398408651'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/03/more-piracy.html' title='&amp; More Piracy'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-1103047235079568206</id><published>2009-03-19T13:25:00.000-07:00</published><updated>2009-03-19T14:06:01.286-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='linguistics'/><title type='text'>Random Linguistic Fact of the Day</title><content type='html'>Technically English (and I think all Germanic languages) doesn't have a future tense. The future is rendered as a &lt;a href="http://en.wikipedia.org/wiki/Grammatical_mood"&gt;mood&lt;/a&gt; in English, using a &lt;a href="http://en.wikipedia.org/wiki/English_modal_auxiliary_verb"&gt;modal&lt;/a&gt; (mood auxiliary) verb, in the same class as (and mutually exclusive with) "can", "may", "must", "would", etc. The past and present tenses, on the other hand, are true tenses, and both in the &lt;a href="http://en.wikipedia.org/wiki/Indicative_mood"&gt;indicative mood&lt;/a&gt; (no modal verb or the "do" dummy modal verb).&lt;br /&gt;&lt;br /&gt;The logical basis for this distinction has to do with the concept of &lt;a href="http://en.wikipedia.org/wiki/Realis_mood"&gt;realis&lt;/a&gt;. Essentially that means what it looks like: realis moods have to do with 'real' things - things which are considered certain to have already happened; while &lt;a href="http://en.wikipedia.org/wiki/Irrealis_mood"&gt;irrealis&lt;/a&gt; moods are not certain for one reason or another. There's a general tendency in language to regard the future as inherantly uncertain, and thus place it in an irrealis mood.&lt;br /&gt;&lt;br /&gt;Whether this is a peculiarity of Germanic languages or is universal among Indo-European languages is unclear. In Latin there is a future tense for the &lt;a href="http://en.wikipedia.org/wiki/Imperative_mood"&gt;imperative mood&lt;/a&gt; (commands - an irealis mood) as well as indicative (events that are certain - a realis mood), but not for &lt;a href="http://en.wikipedia.org/wiki/Subjunctive_mood#Latin_and_the_Romance_languages"&gt;subjunctive&lt;/a&gt; or &lt;a href="http://en.wikipedia.org/wiki/Supine"&gt;supine&lt;/a&gt;, two other irealis moods.&lt;br /&gt;&lt;br /&gt;For trivia value: Caia does not have tense; &lt;a href="http://en.wikipedia.org/wiki/Grammatical_aspect"&gt;aspect&lt;/a&gt; and mood are used to imply tense, and if tense must be made absolutely certain, it can be indicated with adverbs. It has three basic moods (more complex moods are specified with helper verbs or particles): indicative, potential, and hypothetical. As in English, the indicative is used for events considered certain, and is used primarily for past and present tense. Potential mood indicates that an event is possible, but not certain; it is used for the future, among other things (although the preferred method of referring to the future is to reduce it to a certain, indicative present expression such as "I intend to go" or "I want to go", which is more precise). The hypothetical refers to events that are known to be false (hence talking about a hypothetical, counter-factual "what if" situation).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-1103047235079568206?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/1103047235079568206/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=1103047235079568206' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1103047235079568206'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/1103047235079568206'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/03/random-linguistic-fact-of-day_19.html' title='Random Linguistic Fact of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-2596678338117901612</id><published>2009-03-08T16:17:00.000-07:00</published><updated>2009-03-08T16:55:09.075-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='randomthoughts'/><category scheme='http://www.blogger.com/atom/ns#' term='linguistics'/><title type='text'>Random Linguistic Fact of the Day</title><content type='html'>Ever wonder why it's fairly common to create compound nouns from phrases (e.g. bird-watching, card-carrying), but in all these cases the object comes before the verb participle? Based on English word order it should be watching-bird, etc., yet it never is.&lt;br /&gt;&lt;br /&gt;This is probably due to the fact that word order in Proto-Indo-European was very different than the word order used in English and most other Indo-European languages today. In particular, instead of the subject-verb-object order typically used today, PIE (along with more recent ones, like Latin) preferred the subject-object-verb word order. So you might say things like "Avem [bird] spectabam [I watched]" in Latin, which is exactly the order seen in the compounds.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-2596678338117901612?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/2596678338117901612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=2596678338117901612' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2596678338117901612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/2596678338117901612'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/03/random-linguistic-fact-of-day.html' title='Random Linguistic Fact of the Day'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-8023361818037150848</id><published>2009-01-10T20:24:00.000-08:00</published><updated>2009-01-10T20:24:00.934-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><category scheme='http://www.blogger.com/atom/ns#' term='anime'/><title type='text'>Here We Go Again!</title><content type='html'>It's that time again: the beginning of the next anime season; the winter 2009 season, in this case, and things look pretty bleak. &lt;a href="http://that.animeblogger.net/2008/11/28/that-winter-2009-anime-preview/"&gt;THAT Anime Blog&lt;/a&gt; put their preview up quite a while ago. I'd been waiting to post until &lt;a href="http://randomc.animeblogger.net/2009/01/03/winter-2009-preview/"&gt;Random Curiosity&lt;/a&gt; posted theirs, although then I was too lazy to actually post when they did, a week ago or so :P&lt;br /&gt;&lt;br /&gt;So, what's Q looking forward to? Well, not much. I'll probably watch &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6179"&gt;Slayers EVOLUTION-R&lt;/a&gt; because I have a couple of friends that absolutely love that franchise. I downloaded the first episode of &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6026"&gt;White Album&lt;/a&gt; (though I haven't watched it) mainly because of the pretty pictures on Random Curiosity's first episode review; we'll see how that turns out. Other than that, there are three series that, while I can't say they sound great, I'm at least willing to try watching a couple episodes and see - &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=5911"&gt;Chrome Shelled Regios&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6211"&gt;Black God&lt;/a&gt; (listed as "Kurokami the Animation" on Random Curiosity), &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6187"&gt;Kemono no Souja Erin&lt;/a&gt; [The Beast Player Erin] (in no particular order).&lt;br /&gt;&lt;br /&gt;Really, the closest thing to something I'm "looking forward to" on that list is &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6219"&gt;Minami-ke Okaeri&lt;/a&gt; [Minami family, welcome home]. While I wouldn't name it among my favorites, the Minami-ke franchise was sufficiently amusing to make me watch more of it (although it has a bit more cross-dressing than I'd care for).&lt;br /&gt;&lt;br /&gt;I'd say the best stuff ("best" is a relative measure, here) is the two+-season series that are continuing into this season. &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=5909"&gt;Toradora!&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=5841"&gt;Clannad After Story&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6103"&gt;Skip-Beat!&lt;/a&gt;, &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=5975"&gt;Toaru Majutsu no Index&lt;/a&gt; [A Certain Magical Index], and &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=6040"&gt;Tales of the Abyss&lt;/a&gt;, listed vaguely in the order I like them.&lt;br /&gt;&lt;br /&gt;However, I do have good news. I recently saw a mini-review on the sidebar of &lt;a href="http://www.animenewsnetwork.com/"&gt;Anime News Network&lt;/a&gt; for a series by the name of &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=3574"&gt;Higurashi no Naku Koro ni&lt;/a&gt; ["when the cicadas cry", though the official translation is "Higurashi - When They Cry"] that kind of intrigued me; a quick look on AniDB revealed that it was fairly well-rated (although the art style is hideous). So, I grabbed it. While the first roughly 2/3 of the series were sufficiently amusing to hold my interest, the last third of the season really elevated my opinion of it, and made me recommend it to all my friends. However, this series is &lt;span style="font-style: italic;"&gt;not&lt;/span&gt; for the faint of heart, faint of stomach, or those who don't like brutal, tragic stories that don't have happy endings.&lt;br /&gt;&lt;br /&gt;It's a big of a peculiar series. It's structured into a number of arcs (six in the first season), falling into the categories of question arcs and answer arcs. Question arcs are kind of horror/thriller type, where a lot of weird stuff happens, but a lot of it is left unexplained, as to why it happened to begin with. Answer arcs explain parts of the series - why things happened the way they did, and what is behind some of the strange occurrances in question arcs. Oddly, while some of the arcs are compatible, others appear to take place in different universes, as they're mutually exclusive subject matter occurring at the same time, to the same characters. The last arc of the first season, however, suggests that there are actually parallel worlds that aren't entirely separate, and there's some crossover between them; the details are left, presumably, to the second season (&lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=4894"&gt;Higurashi no Naku Koro ni Kai&lt;/a&gt;) or the &lt;a href="http://anidb.net/perl-bin/animedb.pl?show=anime&amp;amp;aid=5634"&gt;OVA&lt;/a&gt;, which I haven't seen yet.&lt;br /&gt;&lt;br /&gt;In any case, I've quickly become attached to it (I watched all 26 episodes in 2 days, which is more than I usually watch of anime), and I'm a bit depressed by running out of the first season to watch.&lt;br /&gt;&lt;br /&gt;You can get it from a variety of places, at least one of which is downloadable online (*cough* &lt;a href="http://www.boxtorrents.com/index.php"&gt;Boxtorrents&lt;/a&gt; *cough*); note that the first season has 26 episodes, while they second has 24. I'd definitely recommend watching it. If you want to start with the best part, I'd say watch episodes 5-8 and 16-21 (both contain the same story, but from different perspectives; the latter explains what was going on in the background of the former, and shows why things turned out the way they did). Though even if you don't skip ahead, I'd recommend watching those two arcs back-to-back at some point, as they're part of the same story.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13053610-8023361818037150848?l=qstuff.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://qstuff.blogspot.com/feeds/8023361818037150848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=13053610&amp;postID=8023361818037150848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8023361818037150848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/13053610/posts/default/8023361818037150848'/><link rel='alternate' type='text/html' href='http://qstuff.blogspot.com/2009/01/here-we-go-again.html' title='Here We Go Again!'/><author><name>Justin Olbrantz (Quantam)</name><uri>http://www.blogger.com/profile/02155606291145056334</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-13053610.post-4440946862122110618</id><published>2008-12-19T09:36:00.000-08:00</published><updated>2008-12-19T09:41:12.752-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='squishy'/><title type='text'>Switching Gears</title><content type='html'>&lt;blockquote&gt;After years of suing thousands of people for allegedly stealing music via the Internet, the recording industry is set to drop its legal assault as it searches for more effective ways to combat online music piracy.&lt;br /&gt;...&lt;br /&gt;Instead, the Recording Industry Association of America said it plans to try an approach that relies on the cooperation of 
