<?xml version="1.0" encoding="UTF-8"?>

<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>codersnotes.com</title>
	<atom:link href="http://www.codersnotes.com/notes/feed" rel="self"
		type="application/rss+xml" />
	<link>http://www.codersnotes.com</link>
	<description>An exciting voyage of programming and fun</description>
	<lastBuildDate>
		Sat, 04 Jun 2022 18:53:50 -0000
	</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>daily</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>

	<item>
		<title>Why Build?</title>
		<link>http://www.codersnotes.com/notes/why-build</link>
		<pubDate>
			Fri, 03 Jun 2022 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/why-build</guid>
		<content:encoded><![CDATA[<blockquote>
<p>"The Centre of the Universe is of course that marvellous land known as Fraggle Rock. It is thus called because it is A Rock and Fraggles Live There.</p>
<p>Fraggles are a noble race. Fearless, dignified, intellectual, they represent the very pinnacle of civilisation and culture. A Fraggle <em>*is*</em>, most assuredly, the best of all possible creatures."</p>
</blockquote>
<p>A long time ago, there used to be a TV show called Fraggle Rock. It was about these strange scraggly creatures, Fraggles, that lived in caves below a lighthouse. The fantastic Fulton Mackay, better known from Porridge, played an old retired sea captain who looked after the lighthouse along with his faithful dog, Sprocket. Interestingly the show was localised with different segments filmed for different countries, so for example in the US version the setting was a quiet inventor's tinkering shed.</p>
<p>And there used to be these other funny little creatures too, Doozers, who were big into construction.</p>
<p>I dunno exactly what it was they built. It was some kind of scaffolding. Looked kinda like crystallized sugar. I seem to recall it was made of radishes. I don't recall the purpose of any of it all anyway, but it certainly seemed important to them if not to anyone else.</p>
<p>And they seemed happy, pushing the their little wheelbarrows around their building sites, while wearing adorable tiny hardhats and other beautifully puppeteered safety equipment. Everything the Fraggles did was chaotic and messy. But not the Doozers. They were the complete opposite: ordered and industrious. Stuff got planned, it got built, and the Doozers were content.</p>
<p>
<div class="caption right"><a href="why-build/trash.jpg#right#thumb"><img alt="" src="why-build/trash.thumb.jpg#right#thumb" title="The Fraggles take life advice from a giant heap of trash"></a><p>The Fraggles take life advice from a giant heap of trash</p>
</div>
</p>
<p>But, I suppose like any great engineering project, there were hazards. If you were a Doozer, working hard day and night, trying to erect some great piece of scaffolding or complete some worthy project, you just had to accept that every now and again, a Fraggle was going to come through and eat some of it.</p>
<p>Strangely they never seemed to be that bothered about it. I mean sure, there'd be a few grumbles here and there. But it never stopped them from getting on with things. It just seemed any large-scale construction effort required a certain Fraggle tax to be accounted for as part of its budget.</p>
<p>In one episode, the Fraggles stopped eating the Doozers creations. It was insensitive, they said, and they were made to utter a solemn vow not to destroy any more constructions. And so the Doozers could keep creating, until eventually their projects filled up the entire world. Once there was no space remaining for the Doozers to build in, they started packing up to go elsewhere. It seemed the Fraggles and the Doozers needed each other to co-exist.</p>
<p>The Doozers never really seemed to consider it much of a problem. Even though they'd spent ages working on something so clearly important to them, building something so beautiful, just to watch it get torn down. <strong>"Architecture is meant to be enjoyed,"</strong> they'd say with a smile. I'm not sure what they meant by that either. To be honest, I feel the Fraggle analogy is possibly starting to fall apart at this point and I'm not sure if I'm the Fraggle or the Doozer in this essay. I suspect I may in fact be the 7ft tall grumpy giant that lives in the garden next to them. I'm starting to regret mentioning the Fraggles now.</p>
<p>The point is, people build. I don't know why. It seems important to <em>them</em> though. Presumably they have a process internally that at least <em>they</em> understand, even if we don't. And it makes them happy.</p>
<p>Which is nice. It's nice to be happy.</p>]]></content:encoded>
	</item>
	<item>
		<title>Bitcoin</title>
		<link>http://www.codersnotes.com/notes/bitcoin</link>
		<pubDate>
			Sun, 03 Oct 2021 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/bitcoin</guid>
		<content:encoded><![CDATA[<div class="admonition disclaimer">
<p class="admonition-title">Disclaimer</p>
<p>I don't know anything about Bitcoin and everything I say is usually wrong.</p>
</div>
<p>Imagine Alice grows turnips in a village. Everyone buys her turnips because hers are the best around. She trades them locally with money.</p>
<p>Then one day, she hears that there's a guy Bob in a village far away that wants to buy her turnips. She can't sell them there herself because it's too far, but hey old Eve there has a horse and cart, so you say <em>"hey Eve, fill that cart up with turnips. Take them to the other village, sell them, you take 10% and I get the rest."</em></p>
<p>So off Eve goes to the other market. Eve sells your turnips on and takes a cut. Then after a while, because of all the new business other people start buying carts, and reselling your turnips elsewhere too.</p>
<p>After a while most of your business is exporting turnips. Then one day, you find out that Eve, and all the other resellers, have been forming a cartel to try and lie about how many turnips they actually sold, and you didn't get nearly the money you should have. And they got away with it because they all outnumber you, and no one saw it happen and no one seems to care.</p>
<p>This happens because the reselling happened far away, where you couldn't see it. The trade you do in person is all fine because you can check it, but once that horse and cart disappears over the horizon then the money kinda disappears with it you see.</p>
<p>What happened was Alice and Bob were trying to have a private transaction, but Eve somehow was able to eavesdrop on it, and siphon money out of the system for herself.</p>
<p>
<div class="caption right"><a href="bitcoin/cartels.png#right#thumb"><img alt="" src="bitcoin/cartels.thumb.png#right#thumb" title="Cartels naturally arise in any system where all players cannot trade directly."></a><p>Cartels naturally arise in any system where all players cannot trade directly.</p>
</div>
</p>
<p>This <em>always</em> happens, because as long as there's a sink/source that can take money far enough so that no one person can see the whole system, scams can always be run. There'll <em>always</em> be an Eve, as long as you don't have direct contact with your customer. Local economies create middle men.</p>
<p>Bitcoin fixes this. With Bitcoin, Alice sells the turnips direct to Bob and Eve is simply hired as a delivery driver. Eve never handles the money. The reason Bitcoin is able to do this is because the blockchain creates, for the first time in history, a historical record of events that we can actually PROVE happened. History books can be inaccurate. If you show me a note saying you have $1000 you could pay me, I can go check with the bank to see if that's correct or not. But the bank could be in a cartel with Eve, you see. They could lie too. Or someone else down the chain could be. Because there's always an Eve, unless you remove all secrets from the world. Which Bitcoin does, because now we can make facts mathematically provable.</p>
<p>Bitcoin removes not just Eve but <em>all</em> middle men. From society. Forever. That's why it's cool.</p>]]></content:encoded>
	</item>
	<item>
		<title>What The Hell Was The Microsoft Network?</title>
		<link>http://www.codersnotes.com/notes/the-microsoft-network</link>
		<pubDate>
			Wed, 29 Aug 2018 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/the-microsoft-network</guid>
		<content:encoded><![CDATA[<p>No, <a href="http://www.msn.com">not that one</a>. Or <a href="https://en.wikipedia.org/wiki/Windows_Live_Messenger">that other one</a>. The letters "MSN" have meant so many things to so many people, a term that's been overloaded with a thousand different meanings. In the same way they throw the words "National Lampoon" onto any random movie to indicate that it claims to be a comedy, they slap the "MSN" label onto <a href="https://en.wikipedia.org/wiki/List_of_services_by_MSN">just about anything</a> so that your poor brain goes "oh, a brand I've heard of" and you get fooled into thinking it must have a certain minimum level of goodness to it.</p>
<p>But I'm talking about the <em>original</em> MSN. Not the simple three-letter acronym we know today, but it's full title: <strong>The Microsoft Network</strong>.</p>
<p>The Microsoft Network was a long forgotten experiment that started back during the Windows 95 Preview Program somewhere around 1994. It was an exciting time for me as a young lad. Having a copy of Windows 95 a year before it came out made me feel Special, Hip, and Cool, three properties which were much sought after by teenage computer nerds. For perhaps the only time in its life, Windows was <em>cool</em>, and so was I.</p>
<p>Microsoft had already released all this fancy new tech with NT 3.1 a few years earlier, but no one noticed so after getting good n' drunk they had another crack at it. Windows 95 replaced the tired old segmented memory model with a glorious flat one where the pointers actually worked how C claimed they did. It dumped the bug-prone co-operative task switcher in favor of a slightly less bug-prone version of pre-emptive multitasking, meaning your machine wouldn't lock up due to busy loops and would have to find exciting new 32-bit ways to lock up instead. It had a <s>plagiarized</s> <em>visionary</em> new shell that presented the file system as a truly window-based navigation model. It was a pretty exciting time for PC owners back then. After all, these new directions brought the PC almost up to the same spec that <a href="http://toastytech.com/guis/amiga1.html">other computers had been enjoying ten years ago</a>.</p>
<p>But it wasn't just the technological advancements. The Chicago betas made you feel like you were part of a secret club. A group of people who could all hang out together in the <em>super-secret clubhouse</em>. But what was this clubhouse, you ask? Well sit down little Timmy, and I'll explain to you what The Microsoft Network actually was.</p>
<p>
<div class="caption right"><a href="the-microsoft-network/tablsrt2.gif#right#thumb"><img alt="" src="the-microsoft-network/tablsrt2.gif#right#thumb" title="The delights of WinCIM accessing CompuServe."></a><p>The delights of WinCIM accessing CompuServe.</p>
</div>
</p>
<p>You see, back in 1994 Facebook hadn't yet invented the Internet, so if you wanted to go online and let your computer transfer viruses to and from other computers, you had to use one of the many private networks. There were lots of them. CompuServe was the biggie. AOL was another, and in the UK they had Cix. Each of them had their own users, their own content and forums, and formed a delightful set of walled gardens that couldn't communicate with each other.</p>
<p>You dialled their phone number on your modem and talked directly to them. Each had their own shitty little piece of software you ran which presented their service, usually in some god-awful MDI-based thing which was barely more than a GDI rewrite of their old BBS interface. CompuServe felt like a dinosaur at the time. They didn't even give you the decency of a <em>username</em> on CompuServe, they gave you a number like you were <a href="https://en.wikipedia.org/wiki/The_Prisoner">Patrick McGoohan</a>. It'd be like <code>71477,134</code> or some rubbish. They always started with a 7, had a bunch of octal digits, and had a comma in the middle. Why? Because that's <a href="https://retrocomputing.stackexchange.com/questions/5086/what-was-the-technical-reason-behind-the-octal-digits-used-for-compuserve-user-i">how the login on PDP-10s worked</a>, which is what CompuServe was powered on. Unbelievably, it seems some poor suckers may still have been paying for CompuServe <a href="https://web.archive.org/web/20171117155520/http://forums.compuserve.com/discussions/Help_Community/_/_/ws-help/187244.1">as recently as last year</a>.</p>
<p>Microsoft looked upon this gluttony of power and figured they wanted a piece of that sweet action. They had big plans for their own Microsoft Network. It was going to be the CompuServe killer. It would have all its own content, and features like being able to make online purchases safely, just like today's App Store allows you to throw money at your phone until Apple's pockets rip open under the weight of that sweet 30% cut.</p>
<p>Of course it was doomed from the start. The raw, unfiltered mess of the Internet was quickly becoming the New Cool Thing, and no-one wanted to sign up for yet another Stupid Proprietary Thing, of which there were an endless supply of. But Microsoft did one thing which got people using it (including myself), at least for a while. They gave it away <em>free</em> to people in the Super Secret Club. That's right, if you had the Windows 95 beta disc because you'd <s>pirated it from somewhere</s> paid the measly $20 bucks to sign up, you could get free access to The Microsoft Network.</p>
<p>I've got kinda sidetracked here waffling on about the history of dial-up BBS systems. What I really want to be concerned with is what made The Microsoft Network unique and interesting: the interface.</p>
<p>The big thing in Windows 95 was their new shell. They wanted <em>everything</em> to go through this. They had this vision of every object in the computer being represented as a shell object, so there would be a seamless intermix between files, documents, system components, you name it. They had this project called Cairo that was supposed to throw out that scruffy old file-based filesystem and bring in a shiny new Object Based File System instead. It never happened, so we'll never know exactly how it might have turned out. But the brave lads at MS didn't give up that easily and so the idea stayed on, admittedly without the tech to back it up, and the principles wormed their way into such glorious developments as The Microsoft Network.</p>
<p>
<div class="caption right"><a href="the-microsoft-network/msn1_02.jpg#right#thumb"><img alt="" src="the-microsoft-network/msn1_02.thumb.jpg#right#thumb" title="Browsing The Microsoft Network."></a><p>Browsing The Microsoft Network.</p>
</div>
</p>
<p>And so The Microsoft Network wasn't a program you loaded like CompuServe. It was part of the OS, with folder icons that looked just like real folders. It was a kind of version of the Web where you could browse online data the same way you browsed your file system. This is what made it cool.</p>
<p>Everything was an object, and everything appeared in its own Explorer window. You could click on the icon for -- oh I don't know, what do humans talk about? Let's say <em>Goat Tickling</em>. You could click on the Goat Tickling BBS, and it'd open up a new window where people talked about Goat Tickling and each message was listed exactly like the "Details" view of a file system directory. From the user's perspective, there was <em>no difference</em> between this and a regular file window. The magic of the extensible shell blended the online world and your own desktop seamlessly, with no need for web browsers or forum software. It all just fell together under the same shared interface.</p>
<p>It's impossible to access this service today though, in case you wanted to take a nostalgic little look, as the servers than ran it have long since been euthanized. But if you're interested, you can watch this <em>delightful</em> and certainly not-at-all dated Microsoft promotional video, where <a href="https://youtu.be/5DqJwmzG6Fk?t=1133">Chandler and Rachel from Friends learn how to look at cat pictures on The Microsoft Network</a>.</p>
<p>
<div class="caption left"><a href="the-microsoft-network/133191-msn.png#left#thumb"><img alt="" src="the-microsoft-network/133191-msn.thumb.png#left#thumb" title="Get yer data right here in Explorer folks!"></a><p>Get yer data right here in Explorer folks!</p>
</div>
</p>
<p>I loved The Microsoft Network back then, even though I knew it was terrible. It felt like there was the germ of a new idea here, something that hadn't been tried before on our poor little consumer computers. It was as if the data was suddenly free of the shackles of being displayed in a program. Data wasn't just a web page, or a program showing its own internal databases. The Microsoft Network made it look like the data was <em>right there</em>, and you could click it and drag it around! For a brief time, back in 1995, it felt like we were on the verge of the true object-oriented web, a world filled with open data and free from the tyranny of the walled gardens.</p>
<p>Of course, like all such things, it turned out to just be a big fat lie.</p>
<p>Microsoft's shell extensions are such a walled garden that even the rest of the OS can't bluff its way in. Open up your Control Panel right now, and right-click on one of the things (e.g. Keyboard). You can select "Create Shortcut", and it'll magically plop a shortcut to that item onto your Desktop.</p>
<aside>
(At least, it will if you've got the classic Control Panel enabled. If you've got it on the defaults it'll probably just give you a list of Helpful Tools, like <i>"Find and fix problems"</i>, <i>"Save backup copies of your files with File History"</i>, or <i>"Search for solutions to your problem online because you sure as hell ain't gonna find them in here"</i>. The new Microsoft UI strategy was conceived when the product manager happened to call the IRS one day, and was faced with a phone menu of vague, unnavigable choices which circle around the thing you really want but never lead to it, causing him to listen for hours while occasionally pressing '5' to hear his choices again. He was impressed by the amount of time he'd managed to waste, and wishing to inflict the same suffering on his own users he immediately wrote a memo ordering everything in Windows to follow the same pattern. Any direct access to information was thrown out and hidden from the user at all costs, in case they might actually manage to change something. I hear in the next Windows build they're actually going to replace Control Panel with a copy of Eliza that's been hooked up to a magic 8-ball. No really, it's true. But I digress.)
</aside>

<p><a href="the-microsoft-network/fake.png#right#thumb"><img alt="" src="the-microsoft-network/fake.thumb.png#right#thumb"></a>
<div class="caption right"><a href="the-microsoft-network/real.png#right#thumb"><img alt="" src="the-microsoft-network/real.thumb.png#right#thumb" title="One of these two is a _real_ shortcut."></a><p>One of these two is a <em>real</em> shortcut.</p>
</div>
</p>
<p>So we've got a shortcut now our our desktop. It looks just like a <em>real</em> shortcut, right? Just like any other file. Now right-click on that shortcut you've made, and see where it points to. What's that, I hear you cry? It points to <code>Control Panel\All Control Panel Items\Keyboard</code>! Where the hell <em>is</em> that? Pop open a command prompt and try and run "dir" on that location. You sure as hell won't get a directory listing of it. And why, you say, is the text displayed as a fixed label? Why can't I <em>change</em> the shortcut's target to a different file, like I can with a regular shortcut?</p>
<p>Unfortunately, like most things involving the Windows shell, these objects
aren't <em>real</em> objects. Well no, I mean presumably <em>some</em> part of the system thinks they are. But they're not to <em>us</em>. They're not things you can just link to like a regular file. They're not like web pages where you can share the link with someone else. They live in their own weird little inaccessible namespace. Explorer knows how to peer over the fence into these little gardens, but no one else does. It's a facade, one designed to make you think you actually know how your computer works.</p>
<p>It was the kind of thing other OSs like Plan 9 were trying to do, except the Plan 9 guys didn't bollocks it up. See what happened was a senior director at Microsoft came in one night around 3am, loaded on blow and Jack Daniels, and shouted to the room "I've got it lads," in a big booming voice that woke up the people struggling to ship Cairo for the third time, "we'll implement it all in COM!" A great sigh rippled around but they knew in their hearts that was how things would be from now on, there was no point fighting it, and thus the great triumph known as the Windows Shell Namespace was born.</p>
<p>Microsoft's shell system made all the same mistakes CompuServe did, just in different ways. They thought numbers were a good way to name things, so you ended up with every shell object being given a 32-digit GUID. And they made it so their content was <em>only</em> linkable (if at all) via these same GUIDs, thus only those knights brave enough to fight the GUID monster may be allowed to enter. So while there might be a way for someone to copy a link to something they saw on The Microsoft Network, good luck actually being able to paste that link into another program, access it via the command line, or send it to a friend.</p>
<p>
<div class="caption right"><a href="the-microsoft-network/openfile.png#right#thumb"><img alt="" src="the-microsoft-network/openfile.thumb.png#right#thumb" title="How Microsoft tell you to select a file."></a><p>How Microsoft tell you to select a file.</p>
</div>
</p>
<p>This is what makes the whole COM system really <em>really</em> stupid. It's like they don't <em>want</em> you to be able to work with it. They <em>want</em> to make it hard for you to access and share data, because code that were to do something reckless like call <code>fopen</code> is code that could run on <em>anyone's</em> operating system, not just theirs. They <em>want</em> to keep you on the phone selecting numbered options, because if you stop doing that you might actually <em>achieve</em> something. And if you go around recklessly <em>inventing</em> new things on your own, you might not need Microsoft any more.</p>
<p>It used to be if you wanted the user to select a file, you'd call <code>GetOpenFileName</code>. That was it, one swift function call and you were done. Now they've deprecated that and are telling you you gotta call <code>CoCreateInstance</code>, have a <code>CLSID_FileOpenDialog</code>, you'll need an <code>CLSCTX_INPROC_SERVER</code> too and probably some <code>IID_PPV_ARGS</code>. Then you'll need a <code>CDialogEventHandler_CreateInstance</code>, and maybe end up with a <code>IShellItem</code>. You'll need about a dozen or so calls to <code>SUCCEEDED(hr)</code> too, in case one of the many internal details you never asked to know about happens to go wrong. Think I'm exaggerating? Check <a href="https://msdn.microsoft.com/en-us/library/Bb776913(v=VS.85).aspx">Microsoft's own documentation on it</a>.</p>
<p>It seems insane, but it's the same trap Microsoft just keep falling into. Hell, just go look at any <a href="https://github.com/Microsoft/DirectX-Graphics-Samples/blob/master/Samples/Desktop/D3D12Fullscreen/src/D3D12Fullscreen.cpp">DirectX 12</a> code to see how they've not learned their lesson.</p>
<p>Phew, I'm exhausted after that long, unnecessary and possibly incoherent COM ramble. Got a little carried away there. Where were we? Ah yes, MSN. The Microsoft Network failed because it was just one more walled garden. One that was walled-off in two ways. One was from a business standpoint, of trying to keep users locked into it and locked off from the rest of the world. But the other was the <em>technical</em> standpoint. It wanted to make it look like the Network was something you had control over, something you could interact with just like you could with your own data. And it was a lovely idea, but that's all it ever was. The thing itself was never more than a facade. Meanwhile those Internet nerds were off pasting hyperlinks around, doing reckless things like setting up their <em>own</em> email addresses and adding new things to the network <em>without having to ask anyone first</em>. And despite The Microsoft Network making every object look so real on the outside that you could just squeeze it and watch the AddRefs ooze out, the Web's simple idea of giving every thing a unique readable location won by a mile. It wasn't the Object Oriented dream we might have hoped for, but <a href="https://www.youtube.com/watch?v=oO8-cKJSLvg"><em>Open Always Wins</em></a>.</p>
<p>The trouble with a walled garden is that if the thing <em>outside</em> the garden is bigger and better than the thing <em>inside</em> the garden, then the wall only serves to keep new customers <em>out</em> rather than lock them in.</p>
<p>So what happened to The Microsoft Network? It barely lasted a year after Win95 shipped before being thrown out and replaced with MSN 2.0, which was a much more web-based experience and opened the doors for the cuddly familiar MSN.com we know and love(?) today, and all still have bookmarked in that IE installation we only switch to when we need to test something.</p>
<p>AOL and Compuserve didn't like it much either. After all, it was eating away at their already rocky marketshare. So they put on their big hat marked "antitrust" and manage to force Microsoft to wedge a big AOL icon on your desktop too. That way the consumer had a <em>choice</em> of which shitty-little service they wished to lock themselves into.</p>
<p>But at least the lessons of The Microsoft Network have been learnt. We don't have that kind of locked-off data any more, it's all fully integrated under a unified banner. At least now I can happily use <code>fopen</code> to read data from a website, right? And backup my email just by dragging folders from Gmail to a local disk. Right guys?</p>
<p>...right?</p>]]></content:encoded>
	</item>
	<item>
		<title>In Search Of The Lost Program</title>
		<link>http://www.codersnotes.com/notes/the-lost-program</link>
		<pubDate>
			Thu, 11 Jan 2018 08:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/the-lost-program</guid>
		<content:encoded><![CDATA[<p>
<div class="caption right"><a href="the-lost-program/lost.jpg#right#thumb"><img alt="" src="the-lost-program/lost.thumb.jpg#right#thumb" title="The Lost Chord."></a><p>The Lost Chord.</p>
</div>
</p>
<p>Programmers just can't seem to stop making new things. You only have to look at how many different unit-test frameworks and build systems there are out there to see that. We're drawn to keep reinventing software that already exists, adding little improvements and new approaches. It's like a disease sometimes, it infects us, attaches to our brains while we sleep and whispers "Code me..."</p>
<p>It results in this explosion of software, all of which does exactly the same thing that all the other software does, except This One's Written In Rust, or This One's Got Python Support. They're not descendants of each other, which might build on previous code, but separate creations that begin anew. And while each may add one new idea, they tend to have forgotten at least one feature that the previous ones already did.</p>
<p>But why? Why can't we just make, say, the perfect build system, and then everyone could just use that? Why do we make so many programming languages and libraries all doing the same thing over and over again?</p>
<h3 id="the-lost-chord">The Lost Chord</h3>
<blockquote>
<p>I heard there was a secret chord, that David played and it pleased the Lord.</p>
</blockquote>
<p>There's this lovely myth in music of the <a href="http://www.gsarchive.net/sullivan/songs/lost_chord/chord.html">Lost Chord</a>. A chord better than any other, considered the Holy Grail of music. And having perhaps heard it clearly in a dream, a musician might spend his whole life circling around it trying to discover the notes that make it up, hoping to recreate the perfection he once briefly tasted.</p>
<p>The thing about a chord, for the non-musicians out there, is it's just a thing composed of at least 3 notes played together. So any old keyboard or guitar could play it, if only you could discover all the right notes to use. It's merely a matter of composition, so <em>surely</em> it would be easy to just hit all the right notes and let the chord ring out? So why haven't we found the secret chord yet?</p>
<p>The answer, somewhat obviously, is because it doesn't exist. At least, it doesn't exist in <em>our</em> world, it can't. The Moody Blues once released an entire album inspired by it, 1968's <a href="https://en.wikipedia.org/wiki/In_Search_of_the_Lost_Chord">"In Search Of The Lost Chord"</a>. This snippet from there perhaps gives some insight:</p>
<blockquote>
<p><em>The Word</em> (The Moody Blues, 1968)</p>
<p>Two notes of the chord, that's our poor scope<br>
But to reach the chord is our life's hope<br>
And to name the chord is important to some<br>
So they give it a word, and the word is...<br>
Om.</p>
</blockquote>
<p>The daydreaming musicians recognize something here. We get two notes, not the three needed. It's not just the we haven't <em>found</em> it, it's that it's unfindable by us. It's a mirage that hangs just on the horizon, but vanishes as you approach it. It's a Rubik's cube where you can get one side done, but then getting the second side done messes up the first one.</p>
<p>
<div class="caption right"><img alt="" src="the-lost-program/mercator.jpg#right" title="The Mercator Projection."><p>The Mercator Projection.</p>
</div>
</p>
<p>Perhaps computers are the same. Are we trying to solve impossible problems? Like a cartographer trying to <a href="http://www.progonos.com/furuti/MapProj/Normal/ProjConf/projConf.html">produce a flat 2D map of the 3D earth</a>, some tasks just <a href="https://www.youtube.com/watch?v=B4UGZEjG02s">aren't possible without at least one compromise</a>. If you try and unpeel the Earth and flatten it out, something's going to end up looking the wrong shape. The <a href="https://en.wikipedia.org/wiki/Mercator_projection">Mercator projection</a>, perhaps the most commonly-used world map view, makes Greenland look bigger than Australia, when in fact Australia is over 3 times bigger.</p>
<p>
<div class="caption right"><img alt="" src="the-lost-program/peirce.jpg#right" title="The Peirce Quincunxial Projection."><p>The Peirce Quincunxial Projection.</p>
</div>
</p>
<p>Or you could try the <a href="https://en.wikipedia.org/wiki/Peirce_quincuncial_projection">Peirce Quincunxial Projection</a>, which has a lower overall distortion, but on the other hand splits Antarctica into four and makes Africa go funny.</p>
<p>The point is, there's no correct way to solve this particular problem, it's simply not possible. The only thing you can really do is to move into a higher dimension, where you can show a full 3D globe.</p>
<p>Maybe the inner truth of programming is something that can't be represented by our simpler world of variables and values, of bytes and registers. Are we just endlessly trying to find new ways to fit 9 bits into an 8-bit byte? Like the story of the <a href="https://en.wikisource.org/wiki/The_poems_of_John_Godfrey_Saxe/The_Blind_Men_and_the_Elephant">blind men trying to describe an elephant</a>, we're all just groping different parts of the perfect program we dreamt of, none of us able to get the full picture at once. Are we just circling around perfection, and never able to achieve it?</p>
<p>It seems to me sometimes that there will never be a One True build system, unit-test framework, or programming language. Every new programming language is destined to play just two notes of the chord, never the third. Perhaps programming is an impossible problem too, one we'll only ever truly overcome once we find a way to escape our current computing flatland and finally learn to move sideways.</p>]]></content:encoded>
	</item>
	<item>
		<title>Something Rotten In The Core</title>
		<link>http://www.codersnotes.com/notes/something-rotten-in-the-core</link>
		<pubDate>
			Tue, 24 Oct 2017 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/something-rotten-in-the-core</guid>
		<content:encoded><![CDATA[<p>There's a key thought of UNIX philosophy which centers around the idea of linking programs together. You know, piping the output from <code>grep</code> into <code>sed</code> and then into <code>sort</code>, that kind of thing. It kinda works well, I guess. For text at least.</p>
<p>But one of the reasons it can work OK is because you, as the end-user writing this little script or command, have full knowledge of the pieces you're building it from. You understand grep, you understand sed, and if any of those pieces suddenly stop working then you can pick the piped command-line apart again and see why. It's a system made up of pieces that <em>you</em> have control over, and most importantly: all the pieces are exposed to you.</p>
<p>This idea spread throughout UNIX, but in ways it should never have. I'm referring here to the misfortune that is debugging.</p>
<p>You see, on UNIX there's GDB. That's the debugger. That's the <em>only</em> debugger. It's very old and has had a lot of work put into it, and as a result it usually works pretty well, at least in terms of functionality. But on every <em>other</em> metric you measure software by, it kinda sucks.</p>
<p>
<div class="caption right"><a href="something-rotten-in-the-core/teletype.jpg#thumb#right"><img alt="" src="something-rotten-in-the-core/teletype.thumb.jpg#thumb#right" title="GDB's intended user interface.&lt;br&gt;(c) Arnold Reinhold, CC-BY-SA"></a><p>GDB's intended user interface.<br>(c) Arnold Reinhold, CC-BY-SA</p>
</div>
</p>
<p>Despite every computer made in the past 40 years having a graphical display, GDB lives in a parallel universe where the framebuffer was never invented and we all still use teletype printers. Teletypes work OK enough for getting output, but for interactive programs it just falls apart.</p>
<p>And so people who didn't want to deal with the pain of GDB invented the "GDB Wrapper" -- a separate piece of software that would show a nice user interface, but internally would call GDB to do the work.</p>
<p>We're not talking about calling out to a library here. We're talking about actually <em>launching</em> an instance of GDB, passing it commands, and parsing the results it prints out. And this is where we get led down a dangerous path.</p>
<p>APIs are hard to begin with. Good API design is very much an art, and it takes a lot of experience to come up with good ones. And the reason so many APIs are bad isn't because someone designed a bad API -- it's that they didn't even realize they were designing an API to begin with.</p>
<p>So much of our software world now is filled with wrappers -- programs that don't actually do the thing themselves, but 'outsource' their work to other programs. It's a stack of layers, and it's not a nice clean stack. I remember something <a href="https://www.youtube.com/watch?v=tK50z_gUpZI">Jeff Roberts</a> once said to me -- the layers grind against each other, and you can feel each one chipping bits away as they collide.</p>
<p>I had the utter delight a few months back of trying to debug something using Qt Creator one day, except I couldn't. It just suddenly one morning refused to start debugging programs. It wouldn't say <em>why</em> of course, it would just sit there doing nothing.</p>
<p>Nothing had changed, at least so I thought. So why the failure? It turned out, after some experimentation, to be because Microsoft's symbol servers were down. That's right, a remote failure on someone else's part meant I couldn't debug locally.</p>
<p>Now of course errors happen in life, and are to be expected. But I didn't <em>get</em> an error. I didn't get a warning. I didn't get anything, except an unresponsive UI. And the reason for this, I think, is precisely <em>because</em> the wrapper wasn't fully aware of all the facts.</p>
<p>Jeff Goldblum said it best in that famous scene from Jurassic Park:</p>
<blockquote>
<p>The problem with the scientific power you've used is it 
didn't require any discipline to attain it.  You read 
what others had done and you took the next step.  You 
didn't earn the knowledge yourselves, so you don't take 
the responsibility for it.  You stood on the shoulders 
of geniuses to accomplish something as fast as you 
could, and before you knew what you had, you patented 
it, packages it, slapped in on a plastic lunch box, and 
now you want to sell it.</p>
</blockquote>
<p>We've seen it hundreds of times in all kinds of software. Functions that return <code>bool</code> instead of an error code. Where did the precise error vanish to? Poof, it's gone! What used to be a useful error message became <code>false</code>, and if you're lucky you'll get a generic "Unexpected error" appearing on screen. And that's if your program is using a <em>library</em>. If it's calling out to a command-line worker, the most likely case is it won't get checked at all and will just get printed out into a log file you'll never find, and then never seen again.</p>
<p>Or networking software that just sits there spinning a cursor when something went wrong. So much user-facing network software is built on top of other programs, like <code>ssh</code> or <code>rsync</code>, and when those things fail they just don't know what to do. And so much of the problem is precisely because they're <em>not</em> using them as libraries, they're using them as command-line utilities. They're using these things that have ill-defined interfaces to begin with, and because it's all based on outputting text, the programmers think they can just look at examples of the output and figure out an API from that.</p>
<p>There's a quote from the great Douglas Adams which I'm sure I've used many times before, but it's just so incredibly apt for most of today's software:</p>
<blockquote>
<p>The major difference between a thing that might go wrong and a thing that
cannot possibly go wrong is that when a thing that cannot possibly go wrong
goes wrong it usually turns out to be impossible to get at and repair.</p>
</blockquote>
<p><a href="something-rotten-in-the-core/pecking.gif#left#thumb"><img alt="" src="something-rotten-in-the-core/pecking.gif#left#thumb"></a></p>
<p>You've all seen those cheap Chinese toys that <em>look</em> like a PlayStation, but inside its just a 6502 and 50 NES games. It's all fake, it's an illusion. It's a nice plastic finish on the outside, but if you were to open it up there's nothing in there. It's a rotten core, wrapped in layers of opaque complexity.</p>
<p>We're making systems that are fragile, because they're just glued on rather than bolted together. We're wrapping complex things up a wrappers that don't take the same responsibilities as the things they rely on. Like Homer's pecking bird in the Simpsons, they work just fine when everything is as expected, but when the slightest change in situation happens then everything breaks.</p>]]></content:encoded>
	</item>
	<item>
		<title>Little Lightmap Tricks</title>
		<link>http://www.codersnotes.com/notes/lightmap-tricks</link>
		<pubDate>
			Tue, 10 Oct 2017 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/lightmap-tricks</guid>
		<content:encoded><![CDATA[<p>Just a quick post today to write down some lightmap lessons I've learned over the years, inspired by Ignacio Castaño's post on his <a href="http://www.ludicon.com/castano/blog/2017/10/lightmap-optimizations-ios/">iOS optimizations for The Witness</a>. Many years ago I helped a little on the Wii port of "Call Of Duty: Modern Warfare", and it reminded me of the "fun" I had rewriting the lightmap system to fit into that. So I thought I'd write up some of the little tips and tricks I picked up along the way. Nothing special here, just some common mistakes to avoid.</p>
<h4 id="dont-put-gaps-in">Don't put gaps in!</h4>
<p>
<div class="caption right"><img alt="" src="lightmap-tricks/remove_gaps.png#right" title="You don't need pixel gaps between each chart."><p>You don't need pixel gaps between each chart.</p>
</div>
</p>
<p>It's surprisingly common to see people generating lightmaps with empty pixels in-between each chart. You don't need to do this! Put them right up against each other without any gaps. If you're worried that maybe you needed the black pixel to stop the charts bleeding into each other, then you're calculating your UVs wrong.</p>
<h4 id="squish-blocks-down">Squish blocks down</h4>
<p>
<div class="caption right"><img alt="" src="lightmap-tricks/squish_solid_areas.png#right" title="Many charts are all the same color -- squish them down."><p>Many charts are all the same color -- squish them down.</p>
</div>
</p>
<p>If all the pixels in the chart are exactly the same color (or near-enough), you don't need to waste space storing all of them. Just shrink the entire chart down to a single pixel. And furthermore (see below), use <em>the same</em> single pixel for all of the shrunken charts.</p>
<h4 id="share-identical-charts">Share identical charts</h4>
<p>
<div class="caption right"><img alt="" src="lightmap-tricks/merge_dupes.png#right" title="Share UVs for identical charts."><p>Share UVs for identical charts.</p>
</div>
</p>
<p>You might imagine that the majority of a lightmap's space is taken up by nice big chunky pieces, like open terrain areas, or the sides of buildings. But in fact, you'll find that probably the majority of the lightmap space is occupied by a thousand little tiny shards of rubbish. Many of these only occupy a single 2x2 or 3x3 block on the lightmap. Now if you think about it, there's only so many 2x2 blocks that can exist in the world. So:</p>
<p>For each chart, search for all previous charts that are the same size and have the same contents (within a given pixel error). If you find any, throw the new chart away and simply re-use the UVs of the old one.</p>
<p>You might even find that this doesn't just work for little 2x2 blocks. If there's any instanced geometry in the level that's facing the same direction, then they'll often have identical lightmaps too. One example would be the side of an apartment block, with many balconies. Because the sun is a directional light, each balcony will have the same shadow cast onto it. So you can get chart re-use in a lot more places than you'd think.</p>
<h4 id="dont-ruin-your-block-compression">Don't ruin your block compression</h4>
<p>
<div class="caption right"><img alt="" src="lightmap-tricks/pad_dxt_blocks.png#right" title="Don't let empty pixels ruin your compression for you."><p>Don't let empty pixels ruin your compression for you.</p>
</div>
</p>
<p>You can get a big benefit by using a block compression scheme for your texture (DXT/BC/etc). But don't just compress your texture without thinking first! DXT stores two colors for each 4x4 block. The pixels you didn't write to on the lightmap will be an empty black. Do you really want to waste one of those colors on storing black? Of course you don't.</p>
<p>For each 4x4 block, fill in the unused pixels with one of the other pixels from the same block (doesn't really matter which).</p>
<h4 id="visual-debugging">Visual debugging</h4>
<p>One of the really cool things I did was to write a little visual debugger -- a small command-line parameter that would pop open an OpenGL window showing the results of the bake. You could fly around and inspect the results, and if you found a strangely black triangle somewhere, you could click on it, and the program would <em>re-run</em> the lighting for that triangle and automatically break into the debugger at the right location. I highly recommend this.</p>
<h4 id="the-scheme-i-used">The scheme I used</h4>
<p>I tried a lot of texture compression schemes out, but here's the one I finally settled on. Bear in mind we were super-tight on memory, so I didn't want to use anything more than 4-5 bits per pixel really.</p>
<p>Like its parent 360/PS3 versions, the Wii port of COD:MW uses a non-HDR lighting engine where the sun's shadow is stored off as a separate lightmap channel. This allows partial time-of-day changes, special effects like lightning flashes, and also allows the total lighting brightness to exceed 1.0, allowing some overbrightening.  I really wanted to keep that scheme for the Wii port, but I didn't want to use any more memory.</p>
<p>The shadow term is stored at full resolution, in the red channel of a DXT1 texture. This consists of the shadow visibility multiplied by the N.L term. This is then blended at runtime with the actual sun color. </p>
<p><a href="lightmap-tricks/diagram.png#thumb#right"><img alt="" src="lightmap-tricks/diagram.thumb.png#thumb#right"></a></p>
<p>The remaining non-sun light is stored a little differently. I split the secondary light into its separate components -- luminance and color. A separate RGB(565) texture stores the color, at quarter resolution. The luminance is stored at full resolution into the <em>green</em> channel of the above full-resolution texture. At runtime, we simply read both textures and multiply them together.</p>
<p>Now, you have to be careful about this. DXT compression relies on correlation between the channels -- you can't just throw any old data into the separate RGB channels and expect it to compress well.</p>
<p>But it turns out that for our purposes, this works great. It tends to be that each area of the world only has one strong light affecting each point (either the primary sun or one of the secondary lights), so the DXT compressor is free to EITHER:</p>
<p>a) If the shadow term is mostly constant, focus its efforts on the secondary luminance. Or,
b) If the shadow term varies, focus on that and let the luminance suffer.</p>
<p>It tends to work out either way though. The human eye is drawn to brightness, so if the luminance gets bad compression then you're probably looking at an area that has strong, varying shadows, and that'll be the thing that stands out anyway. And of course, when you throw the diffuse texture on top it hides a lot of any remaining errors.</p>
<p>Because the quarter-res 16bpp texture has 1/16th the pixels of the high-res 4bpp texture, the total storage space is effectively 5 bits-per-pixel.</p>
<h3 id="summary">Summary</h3>
<p>Well there you go. Nothing that special, but it's nice to write these things down sometimes so they don't get lost. Of course, it's all voxel GI these days so I don't expect this to be of much use, but there it is.</p>
<p>
<div class="caption"><img alt="" src="lightmap-tricks/screenshot.png" title="COD:MW Reflex -- Flashes of lightning were achieved by messing with the sun brightness at runtime."><p>COD:MW Reflex -- Flashes of lightning were achieved by messing with the sun brightness at runtime.</p>
</div>
</p>]]></content:encoded>
	</item>
	<item>
		<title>Why Command And Vector Processors Rock</title>
		<link>http://www.codersnotes.com/notes/command-and-vector-processors</link>
		<pubDate>
			Thu, 07 Sep 2017 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/command-and-vector-processors</guid>
		<content:encoded><![CDATA[<p>I had a Commodore Amiga as a kid. I'm told they were never especially popular in America, but in Europe they were everywhere. Well, sucks to be them I guess.</p>
<p>
<div class="caption right"><a href="command-and-vector-processors/amiga.jpg#thumb#right"><img alt="" src="command-and-vector-processors/amiga.thumb.jpg#thumb#right" title="Image (c) Bill Bertram 2006, CC-BY-2.5"></a><p>Image (c) Bill Bertram 2006, CC-BY-2.5</p>
</div>
</p>
<p>The Amiga was and still is, for its time, the best home computer ever made. It had a clean, powerful CPU architecture. It had an operating system that blended the best parts of CP/M and Unix with none of the unfriendly parts. It had 4-channel digital stereo sound playback in an era when a typical PC had a sound system that was either 0 or 1. It had proper multitasking, which took another ten years to finally arrive on Windows. It was also a completely open platform, unlike todays mobile, console, and store ecosystems. </p>
<p>But most importantly, it had Agnus.</p>
<p>Angus is the name for the main chip inside the Amiga. Its primary role is for graphics, but not as you'd think. The Amiga was unusual compared to most other home computers of the time. A typical early 80s computer has a CPU (usually Z80, 6502, or later the 68000). It would also have a video chip, which would read from the framebuffer RAM and either output pixels directly, or look up the bytes in a tilemap and output that instead. And that was generally as far as it went.</p>
<p>The Amiga, however, wasn't satisified with that. It had a CPU, sure. And it had a video chip ("Denise"), which read in bytes and spat out a video signal. But it didn't stop there. It had a custom-designed ASIC for each part of the machine. The entire hardware was built around these "custom chips" and the means to let them communicate.</p>
<p>Agnus is a kind of "ringmaster" chip. Its main component is the DMA controller (Direct Memory Access). This lets bytes be read from main memory and sent around to the various custom chips as needed. You can think of it as an asynchronous memcpy -- you give it an address and it'll either read or write bytes one at a time to/from the appropriate chip. It supported 25 different DMA channels at once for all the different parts of the machine that needed RAM access.</p>
<p>So what would you want to do with all this DMA? Let's look at one of the biggest examples -- the blitter.</p>
<h3 id="the-blitter">The Blitter</h3>
<p>The blitter was another part of the Agnus chip. It's operation was very simple. You'd give it three source pointers, one destination pointer, and a function ID. It would then read individual bits from memory (processing them 16 at a time), perform an arbitrary bitwise operation on them, and store the result out. You can think of it as a general-purpose bitwise arithmetic chip.</p>
<p>Given three bits (let's call them A,B, and C), there's exactly 8 different combinations that can result from these. So in order to specify your arithmetic function, you just need a lookup table of 8 result bits. This handily fits into a single byte.</p>
<p>Having this kind of bitwise arithmetic was important because, like many machines of the time, the Amiga used bitplanes as a format to store its graphics in.</p>
<p>Let's say you're using 32-color paletted mode. That's 5 bits per pixel you need to store. How do you store that? Well, you could use a byte per pixel, use 5 of the 8 bytes to store your data and leave the other 3 empty. But that's a hell of a waste. Instead, you store it as 5 individual bitplanes, each plane using one bit per pixel. (i.e. each byte contains one bit from eight different pixels)</p>
<p>Now let's apply our blitter to this. Imagine we want to draw a sprite on-screen. We've got it stored as 5 individual bitplanes, plus a sixth 'mask' bitplane to store the transparency. To get the blitter to draw this for us, we set up our three inputs:</p>
<div class="codehilite"><pre><span></span><code>A - The position on the framebuffer we want it at
B - Our sprite source data (1st bitplane)
C - Our sprite transparency mask
</code></pre></div>

<p>We'll need to repeat the whole thing a total of 5 times, one for each sprite bitplane, but that's fine (it's real quick!). The final piece of the puzzle is how we specify how to mix these three inputs. We can build a Boolean truth table to handle it.</p>
<p>Our goal is to use the transparency bit (C) to select EITHER (A) the background data (if C=0), or (B) the sprite data (if C=1). i.e. <code>D = C ? B : A</code>. To figure out our function ID, we just list out all eight cases:</p>
<table>
<thead>
<tr>
<th>A</th>
<th>B</th>
<th>C</th>
<th>D (output)</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>0</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>0</td>
<td>1</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>1</td>
<td>1</td>
</tr>
</tbody>
</table>
<p>If we concatenate all the bits of D together, we get the value 0xD8. This is called a <em>minterm</em>, and it represents our bitwise operation in its entirety.</p>
<p>This "minterm" idea is a pretty powerful one. You can combine elements together to get any bitwise function you like. Want to XOR images? Sure. Want to just clear memory? That works too, just set the ID to 0x00 and ignore all the inputs. You'll still occasionally see systems that use this. Windows, for example, <a href="https://msdn.microsoft.com/en-us/library/windows/desktop/dd145130(v=vs.85).aspx">still uses it for its BitBlt function</a>, although you'd never know that from reading the BitBlt documentation.</p>
<p>To actually program the blitter to do this, we simply write the three source address into three of its registers, write the function ID to another register, and then signal it to start. It'll run in the background while our CPU gets on with other things, and we can either check a flag to see if its finished, or get it to wake the CPU with an interrupt.</p>
<h3 id="the-copper">The Copper</h3>
<div class="caption right" >
    <canvas id="beastanim" width="288" height="200"></canvas>
    <script src="command-and-vector-processors/beast.js"></script>
    <p>Using the COPR to move the screen on each line</p>
</div>

<p>So far we've seen how Agnus contains the blitter functionality, and the DMA controller. But there's one more little secret hidden inside this chip, and that's the co-processor (aka "COPR", or simply "copper" to its friends).</p>
<p>The copper was a completely independent CPU that ran in parallel with the main one. It wasn't a Turing-complete, general-purpose CPU like the 68000. It only had three instructions. It didn't have its own memory or registers, but instead shared main memory (like everything else on the Amiga), and it could directly access many of the registers inside the custom chips.</p>
<p>The copper read its instructions via DMA. This meant you allocated some memory and filled in a program, called a "copper list", by writing 16-bit instructions into it. You then pointed the DMA at that address and started the program. The DMA would fetch each instruction and feed them into the copper.</p>
<p>So what could you do with a CPU that only has three instructions? Let's see what the instructions were:</p>
<div class="codehilite"><pre><span></span><code><span class="n">MOVE</span> <span class="kt">reg</span><span class="p">,</span> <span class="n">value</span>
<span class="n">WAIT</span> <span class="n">X</span><span class="p">,</span> <span class="n">Y</span>
<span class="n">SKIP</span> <span class="n">X</span><span class="p">,</span> <span class="n">Y</span>
</code></pre></div>

<p>That's a pretty simple machine. We can load a value into a register, wait for the raster beam to hit a specific X/Y position, or skip the next instruction if the raster beam is past a specific X/Y position.
Doesn't sound like much at first. If I wanted to write registers I could just do it on the main CPU, right? Why would I want to wait to write registers at a specific time? But there's some surprising effects you can get out of this simple mechanism.</p>
<p>What the copper let you do is to apply different properties to different parts of the screen. You can change the address of the framebuffer on a line-by-line basis, for example, to create parallax scrolling in Shadow Of The Beast (above).</p>
<p>Or you can change the address of the framebuffer at the halfway point on each line, to create a 2-player scrolling split-screen, like in Lemmings: (no other port of Lemmings could do this!)</p>
<p>
<div class="caption"><img alt="" src="command-and-vector-processors/lemmings.gif" title="Lemmings in two-player split mode"><p>Lemmings in two-player split mode</p>
</div>
</p>
<p>Or you could wait till a certain line and change both the color palette AND the frambuffer address, to create a wobbly water effect, like in Ugh:</p>
<p>
<div class="caption"><img alt="" src="command-and-vector-processors/ugh.gif" title="Real-time water refraction in Ugh"><p>Real-time water refraction in Ugh</p>
</div>
</p>
<p>And this wasn't just a trick for games, even the operating system made use of this. If they chose to, the Amiga allowed programs to have their own private screen with a different resolution. Windows suffered for years with this problem -- ever switch back from a DirectX program and see all your icons have moved around on the desktop? Not in Amiga-land. Here, two different programs on different screens can co-exist just by dragging the menu bar down:</p>
<p>
<div class="caption"><img alt="" src="command-and-vector-processors/dpaint.png" title="Two screen resolutions on the same television."><p>Two screen resolutions on the same television.</p>
</div>
</p>
<p>These aren't just different windows you're seeing here. These are <em>different screens</em>, each running at a <em>different resolution</em>! The lower screen is 640x256 at 4 colors and the upper screen is 320x256 at 32 colors. Try that on a PC.</p>
<p>All these effects, and more, are achieved via the simple ability to change settings when <em>you</em> want to, rather than having them fixed at the start of the frame. It didn't require more power to be added to the system, just the flexibility to use the existing system in unusual ways.</p>
<p>If you want to see more creative uses like this, try the excellent <a href="http://codetapper.com/amiga/">codetapper.com</a> which takes apart many Amiga games to see how they do things.</p>
<h3 id="hardware-as-a-tool">Hardware as a tool</h3>
<p>The reason I'm writing all this isn't <em>just</em> to show off how cool the Amiga was. I want to show how its design principles allow new avenues to be opened up.</p>
<p>The Amiga hardware never said "this tool is for this purpose". It gave you a toolbox but let <em>you</em> decide what these things were to be used for. And it allowed each tool to interoperate with the others using common registers and common data formats.</p>
<p>I've presented the blitter here as a thing for processing graphics bitplanes, but it was really just a vector coprocessor for operating on boolean/bitwise data. It could be used for other tasks, and it was. The Amiga's floppy disks were formatted using MFM encoding, which is a kind of edge-based binary encoding. To decode it, you had to process the bit array from disk and look for 0-1 transitions. The blitter provides an ideal tool for doing this with, and the OS made use of it for exactly that. The same kind of tasks we might use a compute kernel for today, perhaps.</p>
<p>The copper, while seeming to be a very simple processor, effectively acted as an amplifier for the power contained within the other chips. It could be viewed perhaps as a <em>metaprocessor</em> -- not doing the work itself but controlling the work of others.</p>
<p>This combination of a vector processor and a control chip is a powerful one. It's so powerful in fact, that the machine you're reading this on now has the same architecture. A modern GPU consists of three parts:</p>
<ul>
<li>
<p>Part a) is a thing that can draw triangles. There's usually special-purpose hardware for doing this. There was a time a few years ago when this was what we thought of as the GPU, but we're seeing less and less of that every year. Games now are doing voxel ray-tracing, and people are using GPUs for lots of things other than just rendering.</p>
</li>
<li>
<p>Part b) is the vector processor, a unit that reads data and runs functions using it. Ours are much more powerful than the old blitter though. We can do full floating-point operations on ours, not just bitwise ops. But it's a more advanced version of the same principle -- a program that operates on many values at once rather than just one.</p>
</li>
<li>
<p>Part c) is the command processor. A modern GPU has a chip that reads instructions from the host CPU, decodes the various draw calls, state changes, etc, and then issues work to the vector processor (for compute kernels). Or, when using rendering APIs, it sends work to the triangle drawer which in turn sends work to the vector processor (either to shade vertices or pixels).</p>
</li>
</ul>
<p>Right now we're a little stuck, however. A modern GPU lets you use its triangle drawer (via OpenGL perhaps), and it lets you use its vector processor (via CUDA perhaps). But the one thing it does <em>not</em> do, on almost any platform (even most consoles), is to let you use the command processor. About the only one I've ever seen that <em>did</em> give you that kind of access was the PlayStation 2, something I'll no doubt write about in a future article.</p>
<p>
<div class="caption left"><a href="command-and-vector-processors/gpu_diagram.png#thumb#left"><img alt="" src="command-and-vector-processors/gpu_diagram.thumb.png#thumb#left" title="Block diagram of a typical GPU. Spot the tiny, almost unnoticed 'host interface', where the whole thing is overseen."></a><p>Block diagram of a typical GPU. Spot the tiny, almost unnoticed 'host interface', where the whole thing is overseen.</p>
</div>
</p>
<p>You see, the Amiga <em>documented</em> its command processor. The designers <em>wanted</em> you to write programs that ran on it. They wanted you to use it for doing all sorts of clever things. They recognized that the power to operate the underlying horsepower directly was something that could amplify the capabilities of a system way past the limits of its original design.</p>
<p>But on Direct3D, or OpenGL, all you can do is call DrawIndexedPrimitive etc. and let it do things on your behalf. You can't build your own copper lists like you used to on the Amiga. Some APIs let you make a command buffer, but they're usually just recording API calls into it. You can't program it with your own logic, or your own algorithms. The 3D driver has the power to do this, but you don't.</p>
<p>The Amiga was a good machine not because of what it was designed to do but because the designers intentionally gave you the flexibility to do things they'd never designed it to do.</p>
<p>The old COPR chip only had three instructions and couldn't do much by itself, but you could use it to make the rest of the system <em>sing</em>. I'm sure the command processors in modern desktops have a much more advanced processor -- I'd love to see what we could do with them given the chance.</p>]]></content:encoded>
	</item>
	<item>
		<title>The Danger Of Opinions</title>
		<link>http://www.codersnotes.com/notes/danger-of-opinions</link>
		<pubDate>
			Sun, 03 Sep 2017 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/danger-of-opinions</guid>
		<content:encoded><![CDATA[<div class="admonition disclaimer">
<p class="admonition-title">Disclaimer</p>
<p>Warning: this post may contain <em>opinions</em>. If you are allergic to opinions, please try the associated reddit thread instead where you will be safe from them.</p>
</div>
<p>There's two schools of thought about how we should treat computing. One thinks programming should be about writing things to best reflect the truth of how they will be executed (C, C++, Pascal, Go, Rust, etc). The other thinks we should writing against some universal ideal, and the computer should just deal with that for us (Python, Ruby, Lisp, JavaScript, etc).</p>
<p>For years, <a href="https://www.youtube.com/watch?v=2Op3QLzMgSY">MIT taught their SICP course</a> using Scheme. And you know the weird thing about that? No computers involved at all. It was all just done on a whiteboard, using symbols and parenthesis. No registers, no instructions, no memory. It showed you what computing really was -- an abstract concept that isn't tied to any implementation. The idea that computing doesn't actually require a computer is somewhat alien to many native C++ programmers.</p>
<p>Then you've also got the engineering crowd. People like me whose first exposure to computers was that 8-bit home computer your Dad brought home one day in the 80s. I didn't grow up in a world of evaluation, expressions, and functions. The computer <em>I</em> had knew only about bytes, and how to move them about in memory. It was always about <em>how</em> things get done. What use were abstract concepts in a world where you needed to <em>do</em> specific things in order to see the results?</p>
<p>These two groups often fall under the banners of "static" and "dynamic" typing, and it's perhaps no coincidence. Static typing tries to tell the computer exactly what needs to be done, at the expense of moving the program further away from the abstract description. Dynamic typing expects the computer to figure things out, so that the human can just write things in a nice clean manner.</p>
<p>Which leads on to the ultimate question of programming: Should programs be written for the benefit of humans or for computers? Exactly whom are we trying to make it easier for?</p>
<p>It's a simple point but you see the repercussions of this appearing everywhere, hundreds of little design decisions that push programming further into two camps. UNIX, for example, demands a case-sensitive file system, on the grounds that the file system can be done more efficiently if its only concerned with matching bytestrings. Windows says that being able to create two files with the same name but different cases isn't useful to humans, and is only confusing. Why should humans have to keep track of where the capitals were placed, and why should auto-complete suddenly stop working because I forgot to hold SHIFT?</p>
<p>So which is right? Which is better? Should computers adapt to us or should we adapt to computers?</p>
<p>There's a book I love by Robert M. Pirsig called <a href="https://www.amazon.com/Zen-Art-Motorcycle-Maintenance-Inquiry/dp/0060589469">"Zen and the Art of Motorcycle Maintenance"</a>, which contains over 500 pages of pseudo-philosophical bullshit (oh who am I kidding, I still love it) centered around the idea of "quality". It's got this lovely disclaimer at the front where the author notes that the book doesn't really have anything to do with Zen Buddhism, and "it's not very factual on motorcycles either."</p>
<p>The central pillar of the book is what he calls the "classical" vs. "romantic" ideals. The classical, he says, is concerned with what something <em>is</em> and how it works. The classical viewpoint wants to know how their motorcycle works, how to recognize where that weird knocking noise is coming from, and wants to tune their engine to keep it running well.</p>
<p>The romantic viewpoint is instead concerned with how we see something. It's not important how something works, but how we see and use it. The romantic person wants to use their motorcycle to drive along beautiful mountain roads, and use it to get to far-away places.</p>
<p>The classical person sees a rainbow and wonders how it formed, and how the rain might reflect the sun like that. The romantic person sees a rainbow and wants to show others, and paint a picture of it.</p>
<p>This two-sided philosophy is found throughout the whole of human life, and especially in computers. One of the things I love about computer programming is that it's one of those areas where we actually get to use both at the same time, even within the same program. It's what makes a game developer want to be an artist <em>or</em> a programmer. And yet the game needs both to work.</p>
<p>So which is better? Well unsurprisingly, neither. You need both viewpoints, sometimes at the same time. And that's the weird part. How can two opposing ideas both be correct?</p>
<p>But they can.</p>
<p>I remember once talking to an artist friend of mine. We were talking about computer animation, and the subject of IK (<a href="https://www.youtube.com/watch?v=iRZ2Sh5-XuM">inverse kinematics</a>) came up. What puzzled me is that he wasn't a big fan of it. Now to me as a programmer, it seemed an obvious choice. Of <em>course</em> IK is a better way to do things. You just tell the arm or leg or whatever where you want it to go, and it automatically moves the elbows and knees and such for you. So surely that's less work, and therefore better?</p>
<p>But he explained things to me. You remember when as a kid, you drew stick men? Well in my mind that's how the human skeleton looked. But he explained about "clavicles", something I barely even knew existed but in fact drive the whole upper armature. And he explained how the best algorithm in the world isn't going to give you the results you want if there's more than one solution available. What had seemed a simple "pointing a finger" problem was unfolding into a world where you had to try and teach the computer how to be an artist. It slowly dawned on me that I didn't have the full experience of the problems he was describing, and couldn't make a case to argue back with.</p>
<p>It's weird when you suddenly realize that there's a separate world out there that you're not an expert in. It certainly changed my outlook on things. I think there's a lot of programmers who still haven't had that moment, and still live in a world where they believe they know everything.</p>
<p>Did that make me wrong about IK? Well, no. It's still useful. Did that make him right? Maybe, maybe not. But what it shows is that you can't have a discussion one way or the other unless you actually know a little about the other viewpoint.</p>
<p>Issues aren't black and white. And sometimes you can have two opposing viewpoints that are both valid. Programmers hate this. It's very un-pythonic.</p>
<p>Did you ever have an experience where someone you'd greatly respected suddenly said something you strongly disagreed with? Does that invalidate all the things they said that you did like? Do you stop talking to your best friend because you found out he voted Republican?</p>
<p>Complex issues can't just be simplified down into tribal arguments of us-vs-them, or solved by just shouting at the other person until they go away. We need to get over this cultural idea we have where anyone who disagrees with us is literally Hitler. It's OK to disagree with someone. And just because we disagree with someone doesn't make them wrong. It's possible for two people to disagree and yet they both still are correct. It's so common, especially in the media, for someone who changes their mind later on to be labeled a hypocrite. "But last year," they cry, "you said this thing. Now you're saying the other!". Yet the ability to change our mind is the most important thing we have. An opinion that is rock-solidly fixed in place is just tribal politics. Opinions <em>should</em> be swayable via convincing arguments.</p>
<p>On the one hand it's easy to look at things like the direction the C++ committee is taking and laugh; C++ has become an insane language that no one person has a hope of understanding. But they definitely seem to be heading towards a destination, perhaps if only by accident. What are they actually trying to achieve? A language where you can do anything, but only at compile time? Perhaps Python is a cleaner approach, by pushing all problems to runtime, but even they're now starting to realize that maybe type annotations are a useful feature.</p>
<p>But on the other hand, you've got languages like JavaScript, where they've just this year invented co-routines and are now treating it like the second-coming. And compiling source code into a binary form is still considered a great unsolved problem in computer science. And yet... there's still this "and yet" that hangs around with it. I mean can you imagine trying to write web-apps in C? At least JavaScript has a string type.</p>
<p>But we need both. The idea of the "one true" anything is bullshit. There will always be different sides, with different ideals. And that's fine. We <em>need</em> that. But what we don't need is us-vs-them. People need more exposure to different ideas. Programmers need to try out different languages. Webdevs could learn a hell of a lot from <a href="http://oldmachinery.blogspot.com/2014/04/zx-sprites.html">trying to write a Z80 program</a>. And a lot of GPU shader guys could learn a thing or two from watching how <a href="https://www.youtube.com/watch?v=KmoRz01bm0Y">Bob Ross can manage to paint a tree without knowing how sub-surface scattering works</a>. Because let me tell you, however you've been doing things so far, there's a whole different approach that other people have been successfully using that you have no idea about.</p>
<p>I dunno where I'm going with all this. I just figured I'd write some of these rambling thoughts down, although <a href="https://en.wikipedia.org/wiki/Google%27s_Ideological_Echo_Chamber">putting your thoughts into words can get you fired these days</a>. Probably best just to stay absolutely quiet and avoid doing anything that may or may not cause two <a href="http://buttersafe.com/2015/06/18/allow-me-to-share/">opinions</a> to form. We do have to be careful, you know. Sometimes we can create a difference of opinion so vast that the universe has no option but to <a href="http://www.woodbetween.world/2012/08/the-berenstein-bears-we-are-living-in.html">bifurcate in order to accept both</a>.</p>]]></content:encoded>
	</item>
	<item>
		<title>Disassembling Jak &amp; Daxter</title>
		<link>http://www.codersnotes.com/notes/disassembling-jak</link>
		<pubDate>
			Thu, 12 Jan 2017 08:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/disassembling-jak</guid>
		<content:encoded><![CDATA[<div class="admonition disclaimer">
<p class="admonition-title">Disclaimer</p>
<p>I don't work at Naughty Dog, and I don't have any secret knowledge of Jak &amp; Daxter, except what I figured out myself from the disc. So a lot of this may well be wrong. Take a pinch of salt with it.</p>
</div>
<p>
<div class="caption right"><a href="disassembling-jak/screenshot.jpg#right#thumb"><img alt="" src="disassembling-jak/screenshot.thumb.jpg#right#thumb" title="The massive world of Jak &amp; Daxter"></a><p>The massive world of Jak &amp; Daxter</p>
</div>
</p>
<p>I've always had a fascination with Jak &amp; Daxter ever since it came out, way back in 2001 on the PlayStation 2. It was one of the first 3D games I'd actually seen run at 60Hz. I was used to PC games like Quake which were software rendered, or games like Mario 64 which I played (and completed!) on UltraHLE at a woefully poor framerate. But Jak &amp; Daxter, hereafter referred to as <strong>J&amp;D</strong>, blew me away.</p>
<p>Here was a game running at a silky-smooth 60Hz, never missing a beat, and somehow managing to draw more polygons than any other game out there. A game where you could see and explore a vast world with no boundaries. No load screens, no pauses, no LOD pops. It all just fit together perfectly. I had to know more.</p>
<p>The J&amp;D engine may possibly be one of the greatest engines ever made. Of course, because it's not open source, it doesn't get the recognition that more famous engines like Quake get. There's not much information out there about it, but there's a few snippets here and there. The most important for you to read would be Stephen White's 2003 GDC talk, <em>"The Technology Of Jak &amp; Daxter"</em>, which I can't find a link to any more but I've mirrored here:</p>
<div class="admonition link">
<p class="admonition-title">Link</p>
<p><strong> The Technology Of Jak &amp; Daxter, Stephen White (GDC 2003) </strong></p>
<ul>
<li><a href="disassembling-jak/White_Stephen.ppt">Powerpoint slides</a></li>
<li><a href="disassembling-jak/talk.mp3">Audio</a></li>
</ul>
<p>The audio contains some additional Q&amp;A not in the slides.</p>
</div>
<p>There's a lot to talk about, but today I'm going to ignore all the cool graphics tech and such, because I want to focus on the most amazing element: <strong>GOAL</strong></p>
<p>GOAL, standing for <em>"Game Oriented Assembly Lisp"</em>, is the programming language J&amp;D is written in. All of it. I want to really nail this point home here -- some people think it's some kind of bytecoded scripting language. It isn't. GOAL is a fully natively-compiled general purpose programming language, and the <em>whole game</em> is written in it.</p>
<p>It's a hell of a thing, when you think about it. To create your own programming language, <em>from scratch</em>, and then write the <em>entire game engine in it</em>. I don't know of any other games out there that do that.</p>
<p>The only part of the game not written in GOAL is the loader/linker, which is written in C++. This is the equivalent of their DLL loader; it's just a simple stub program to load the rest. And this is what this article will be picking apart, as it forms the gateway to everything else.</p>
<p>Because GOAL has its origins in Lisp, one of it's hallmarks is that symbols are considered a first-class datatype. There is no offline linker, everything is dynamically linked. Therefore the symbol table <em>must</em> be present in the runtime data. What this means is that if we can understand the data format, we can get a <strong>complete symbolic disassembly</strong> of the whole game.</p>
<p>If you want to follow along at home, you'll need a copy of the PS2 J&amp;D disc or ISO, and the source code I've posted at the end here.</p>
<h3 id="the-loader">The loader</h3>
<p>Let's start at the loader. This is the first thing that loads, and is just a regular PS2 ELF compiled with gcc. For whatever reason (lack of attention possibly), Naughty Dog forgot to strip the ELF symbols from this file, which means we can open it up in any MIPS disassembler and follow its logic through.</p>
<p>The function of the loader is simple. It sits waiting, and when new data arrives from wherever, it allocates space on the heap and copies the data there. It then relocates the pointers to the new address, and patches up any references to the global symbol table. Once this is done the data is ready to go. That's basically it; there's no VM or interpreter here.</p>
<p>The loader generally tracks 3 different memory heaps -- the common heap, and two level heaps. The game has two levels loaded at any one time, each getting their own self-contained heap (this is what allows you to seamlessly walk from one to another). The common heap contains the core engine code and data. The loader just uses a simple bump allocator to throw new data on the end. Once the level is finished with, it just throws out the entire heap and starts again.</p>
<p>So where does the loader get its data from? First we need to examine the file formats used here. If you look on the disc, the main files used here are called "CGO" and "DGO". There's no actual difference between them, I presume the names just reflect the usage (code/data?). It tends to be that CGO files are loaded into the common heap, and DGO files are loaded into the level heaps. However, don't be confused by the names -- just because they <em>imply</em> code and data separately, the contents are in fact mixed and can contain both code and data interchangeably. In fact, as we'll see later, GOAL doesn't really distinguish the two concepts.</p>
<p>The DGO format is real simple. There's a simple header, and then it's just a bunch of binary files concatenated together. It's closer to a ZIP archive than it is to something like ELF. The DGO is just a way of delivering binary blobs one at a time.</p>
<p>In the retail version, the IOP (the PS2s input/output processor) delivers the DGO file as-is into the loader when requested. In the development builds however, they also listen on a network port for incoming binaries. This is how their development process works -- they can compile new source files on their development machine and stream them straight into the PS2 while it's running. The target PS2 doesn't even know where the files came from, it just loads them in like any other.</p>
<p>It's not really fair to call this "hotloading", it's really just "loading", as updating the game with new code/data is no different than loading it in the first place. This is made possible by the dynamic symbol table in the linker, which we'll look at later in the top-level section discussion.</p>
<p>So, we can easily write a little program to pop open a DGO and extract the files within. They don't have an official extension but I'll refer to them as ".go.bin", assuming they were compiled from a ".go" originally. But what do these binaries exactly contain?</p>
<p>A .go.bin is basically the equivalent of a .OBJ file from a normal C++ compiler. It contains 3 sections, as well as relocation tables to patch them with:</p>
<ul>
<li>the <code>top-level</code> segment</li>
<li>the <code>main</code> segment</li>
<li>the <code>debug</code> segment</li>
</ul>
<p>These are loaded in-place by the loader, which makes loading very efficient. The loader does not have to actually parse the data or even know what it is. As far as it's concerned, we're just loading 3 big chunks of data in and then patching them up afterwards.</p>
<h3 id="the-top-level-segment">The top-level segment</h3>
<p>The <code>top-level</code> segment contains everything at global scope from the source file. Because this only executes once, the loader loads it, runs it, and then throws it straight away. Its main purpose is to register functions into the global symbol table. Because functions are first-class objects in GOAL (like most other things), they're just function pointers. So registering a function is simply a matter of storing a pointer to it in the symbol table.</p>
<p>This means that every single function call in J&amp;D goes through a pointer (i.e. is a virtual function). People always used to tell me this was bad on the PS2 as, oh I don't know, DCACHE misses or something. Well seeing as J&amp;D is one of the best performing games on the system (or any system), it doesn't seem to have done them any harm.</p>
<p>Here's an example excerpt of a <code>top-level</code> segment:</p>
<div class="codehilite"><pre><span></span><code><span class="o">;</span> <span class="nx">eye</span>

<span class="o">;==================================================================</span>
    <span class="p">.</span><span class="nx">segment</span> <span class="nx">top</span><span class="o">-</span><span class="nx">level</span><span class="o">-</span><span class="nx">segment</span>
<span class="o">;==================================================================</span>


<span class="o">;------------------------------------------------------------------</span>
    <span class="p">.</span><span class="nx">type</span> <span class="kd">function</span>
<span class="nx">goal</span><span class="o">-</span><span class="nx">entry</span><span class="o">:</span>
    <span class="nx">lui</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L35</span>
    <span class="nx">or</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L35</span>
    <span class="nx">sw</span> <span class="nx">v1</span><span class="o">,</span> <span class="o">*</span><span class="nx">eye</span><span class="o">-</span><span class="nx">work</span><span class="o">*</span><span class="p">(</span><span class="nx">s7</span><span class="p">)</span>
    <span class="nx">lui</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L26</span>
    <span class="nx">or</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L26</span>
    <span class="nx">sw</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">render</span><span class="o">-</span><span class="nx">eyes</span><span class="p">(</span><span class="nx">s7</span><span class="p">)</span>
    <span class="nx">lui</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L12</span>
    <span class="nx">or</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L12</span>
    <span class="nx">sw</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">update</span><span class="o">-</span><span class="nx">eyes</span><span class="p">(</span><span class="nx">s7</span><span class="p">)</span>
    <span class="nx">lui</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L11</span>
    <span class="nx">or</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L11</span>
    <span class="nx">sw</span> <span class="nx">v1</span><span class="o">,</span> <span class="kd">get</span><span class="o">-</span><span class="nx">eye</span><span class="o">-</span><span class="nx">block</span><span class="p">(</span><span class="nx">s7</span><span class="p">)</span>
    <span class="nx">lui</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L10</span>
    <span class="nx">or</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L10</span>
    <span class="nx">sw</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">convert</span><span class="o">-</span><span class="nx">eye</span><span class="o">-</span><span class="nx">data</span><span class="p">(</span><span class="nx">s7</span><span class="p">)</span>
    <span class="nx">lui</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L1</span>
    <span class="nx">or</span> <span class="nx">v0</span><span class="o">,</span> <span class="nx">v1</span><span class="o">,</span> <span class="nx">L1</span>
    <span class="nx">sw</span> <span class="nx">v0</span><span class="o">,</span> <span class="nx">merc</span><span class="o">-</span><span class="nx">eye</span><span class="o">-</span><span class="nx">anim</span><span class="p">(</span><span class="nx">s7</span><span class="p">)</span>
    <span class="nx">jr</span> <span class="nx">ra</span>
    <span class="nx">daddu</span> <span class="nx">sp</span><span class="o">,</span> <span class="nx">sp</span><span class="o">,</span> <span class="nx">r0</span>
</code></pre></div>

<p>In this example, what we're doing is loading the address of a function (e.g. <code>render-eyes</code>) and storing it at an offset into the global symbol table (register s7). Note that GOAL symbol names can happily contain dashes, asterisks, and other Lispisms. GOAL keeps a pointer to the symbol table in register S7 at all times, and all global variables/functions are always referenced via this.</p>
<p>So when this file is loaded into the system, it simply registers the existence of 6 named global objects, and then returns.</p>
<p>I'll give you a brief example of how something like this might be generated. Imagine the following C function:</p>
<div class="codehilite"><pre><span></span><code><span class="kt">int</span><span class="w"> </span><span class="nf">my_function</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="p">;</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>In GOAL, you might write this in a more Lispy syntax: (I guessed at the syntax from snippets I've seen online, don't peek too closely)</p>
<div class="codehilite"><pre><span></span><code><span class="p">(</span><span class="nb">defun</span> <span class="nv">my_function</span> <span class="p">((</span><span class="nv">x</span> <span class="nv">int</span><span class="p">)</span> <span class="p">(</span><span class="nv">y</span> <span class="nv">int</span><span class="p">))</span>
    <span class="p">(</span><span class="nb">return</span> <span class="p">(</span><span class="nb">+</span> <span class="nv">x</span> <span class="nv">y</span><span class="p">)))</span>
</code></pre></div>

<p>Looks similar on first inspection, but the key difference is <code>defun</code> (short in Lisp for "define function"). This is a <strong>macro</strong>. We're not actually defining the function ourselves here, what we're doing is passing our code <em>into</em> the "define function" macro. The macro will run at compile time and rewrite our code, and we'll end up with something like this:</p>
<div class="codehilite"><pre><span></span><code><span class="c1">// top-level segment:</span>
<span class="n">symbols</span><span class="p">[</span><span class="s">&quot;my_function&quot;</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">&amp;</span><span class="n">L1</span><span class="p">;</span><span class="w"> </span><span class="c1">// assign fn ptr to symbol</span>
<span class="c1">// main segment:</span>
<span class="kt">int</span><span class="w"> </span><span class="nf">L1</span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">x</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">y</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">x</span><span class="o">+</span><span class="n">y</span><span class="p">;</span><span class="w"> </span><span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>So effectively, the top-level segment is just doing <em>at runtime</em> the work that most compilers do at <em>compile time</em>. Instead of writing symbol tables into an ELF file, we set it up ourselves upon loading.</p>
<h3 id="the-main-segment">The main segment</h3>
<p>The main segment contains the real work. Because this is just a binary chunk, it could contain anything. Typically it tends to be either a set of function bodies, or some data structures containing art data. Either way, the top-level segment will refer to these objects and patch them into the running system.</p>
<p>For me, this is one of the most beautiful aspects of the GOAL system; the mixing of code and data. The system just doesn't care. There's no code in GOAL to, for example, parse an XML file into a structure. It's just not needed. If you want to fill in data, you just embed that data right into the binary. I wrote about this way back in my old article, <a href="../the-joy-of-incbin">The Joy Of INCBIN</a>. GOAL takes this idea to its extreme. Textures, models, etc, are all processed by offline tools which write out .go files, which the compiler then just packages up like any other data set.</p>
<p>As far as GOAL is concerned, a function body is just an object like any other, no different from an array or a struct. Each allocated GOAL object has a 4-byte header in front of it which contains a pointer to its type, used for both debugging and runtime polymorphism. Note that I didn't say "type debugging information", I said "type". This is because in GOAL, a type is itself an object as well. You can even create new types at runtime if you like.</p>
<h3 id="the-debug-segment">The debug segment</h3>
<p>Lastly we have the debug segment. The game doesn't normally load this in a retail build, it just skips over it. During development however, it contains assorted extra information used for debugging. In a regular ELF binary, you might expect to find encoded DWARF data or some other format that described all the symbols and types within. Well that's not how GOAL works.</p>
<p>GOAL can't list the symbols within the file because there aren't any. Remember, we patched the symbols into the system ourselves in the top-level segment? The <em>code itself</em> decides what to assign to what symbol at runtime, not compile time.</p>
<p>It also can't list the type information, because types are a purely runtime construct too. That's not to say that this is a dynamically-typed language like Lisp or Python, because it isn't. The compiler emits static native code assuming the layout of types, just like a C++ compiler would. The key to understanding GOAL is to realize that types are just something the runtime lets you create at will, and the compiler is just making use of that facility in advance.</p>
<p>So if there's no type info here and no symbol table here, what <em>is</em> here? Well, it tends to just contain a bunch of functions (probably compiler-generated) that know how to print out and inspect the contents of the types the compiler made.</p>
<p>GOAL never had a source-line debugger, as far as I know, although there's no reason it couldn't given some effort to write one. (edit: <a href="https://news.ycombinator.com/item?id=13386669">wrong, see here</a>) So it seems like the main mechanism Naughty Dog used to debug with was to pull up a console and enter commands to print and inspect various data themselves. (Remember, the system can compile a new single-line function and download it straight into the loader at any time! This gives you a free debug console.)</p>
<p>That's not actually as bad as it sounds; bear in mind this is a fully live-editable system, so if there's a function you want to investigate you can easily just patch in a printf <em>while the game's running</em> and mess around with it.</p>
<h3 id="getting-a-disassembly">Getting a disassembly</h3>
<p>So that's pretty much all there is to loading compiled GO files. You can disassemble the ELF loader to figure out the exact file format, and what with having the ELF symbols for the loader available, it's not that hard to replicate the function of the loader ourselves.</p>
<p>So I did.</p>
<p>Below is a small program that loads DGOs, disassembles them back into MIPS assembly, and writes it all out. The assembly format isn't <em>quite</em> standard, as there's a few things the <code>.go.bin</code> format needs that a regular assembler wouldn't provide. In particular it would need to understand how to write the symbol names used into the relocation table, and how to prefix each stored object with a pointer to its type.</p>
<p>I suspect most people won't be that interested to actually pick through it all themselves, but still, here it is. Let me know if you find any of it interesting!</p>
<ul>
<li><a href="https://github.com/rmitton/goaldis">https://github.com/rmitton/goaldis</a> - My command-line disassembler</li>
</ul>]]></content:encoded>
	</item>
	<item>
		<title>Converging Towards Disneyland</title>
		<link>http://www.codersnotes.com/notes/converging-towards-disneyland</link>
		<pubDate>
			Mon, 19 Dec 2016 08:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/converging-towards-disneyland</guid>
		<content:encoded><![CDATA[<div class="admonition warning">
<p class="admonition-title">Warning</p>
<p>Contains (very minor) spoilers for The Witness.</p>
</div>
<p><a href="converging-towards-disneyland/witness_island.jpg#thumb#right"><img alt="" src="converging-towards-disneyland/witness_island.thumb.jpg#thumb#right"></a></p>
<p>Jonathan Blow's 2016 game <a href="http://the-witness.net/news/">The Witness</a> received high praise from most reviewers. Personally, I loved the island and the environmental puzzles, but I hated all the stupid little NP-hard slidey-line puzzles. I'm not here to moan about that today though. Let's talk about layout.</p>
<p>The island itself is an absolute joy to explore. No corner of it is wasted, nothing is filler. Everywhere you look you'll find some new little piece of entertainment. It's designed for you to be able to wander at will and always find new things.</p>
<p><a href="converging-towards-disneyland/witness_map.jpg#thumb#left"><img alt="" src="converging-towards-disneyland/witness_map.thumb.jpg#thumb#left"></a></p>
<p>Yet as I uncovered the whole island, something about it struck me as familiar. A feeling I'd seen something like this before. It wasn't until I found the in-game map that I realized what it was.</p>
<p>Imagine you start from the cove at the bottom. You disembark the boat, and venture forth to the buildings you see. The island has a town in the middle which forms the main hub of the island. North from there leads to the castle centerpiece, or you can wander out to any of the puzzle areas that fill up the rest of the island. Surrounding the island is a transport system, the boat, to let you move around quickly. The game culminates within the giant mountain to the south-east.</p>
<p>Now the game itself doesn't actually start you via that route -- instead you start in the bottom-left, where you're encouraged (but not strictly required) to explore some of the puzzle regions there first. This is because it wants to teach you about the game world one step at a time. However, once you advance past a certain point it becomes clear that the town area is the part you'll keep coming back to.</p>
<p>Here's an (official) labeled map of the different areas in the island. Note that the town is labeled as "hub":</p>
<p><img alt="" src="converging-towards-disneyland/witness_areas.jpg"></p>
<p>Seeing it yet? OK I'll admit perhaps I'm stretching a little here, but... it's Disneyland, right? Not literally of course, but I can't help notice the design similarities. Compare against this historical map of the park:</p>
<p><img alt="" src="converging-towards-disneyland/disney.jpg"></p>
<p>It's the same design. Disneyland has a monorail around the perimeter; the Witness has a boat. Disneyland has a town hub and castle in the center, so does the Witness. Space Mountain became the mountain, and sits in the same corner of the island as its real-life counterpart. And like the real-life one, it's hollow on the inside. A visitor wanders around the park's attractions, but always keeps coming back to Main Street where the shops are.</p>
<p><a href="converging-towards-disneyland/shipwreck.jpg#thumb#left"><img alt="" src="converging-towards-disneyland/shipwreck.thumb.jpg#thumb#left"></a></p>
<p>In The Witness, if you take the boat all the way around the island, you'll eventually be taken on a little ride through these sunken shipwreck ruins. Now admittedly there's no little people singing "It's A Small World" (thank god), but I definitely got the same vibes of going on a little boat ride through an indoor exhibit. It's even in the same top-right area of the map.</p>
<p>The island of The Witness definitely <em>isn't</em> Disneyland, and only slim elements match up, but in terms of design and layout there's this nagging feeling of subconscious echoes.</p>
<hr>
<p>
<div class="caption right"><a href="converging-towards-disneyland/zelda.jpg#thumb#right"><img alt="" src="converging-towards-disneyland/zelda.thumb.jpg#thumb#right" title="Zelda, Phillips CD-i, 1993"></a><p>Zelda, Phillips CD-i, 1993</p>
</div>
</p>
<p>OK, maybe it's just my imagination, I dunno. But I'm not the only one to notice common themes between The Witness's island and other designed experiences. <a href="https://twitter.com/tydaspy/status/767904990346170368">@tydaspy pointed out</a> the similarities in style with the world map from the 1993 Zelda game "The Wand Of Gamelon" released on the Phillips CD-i.</p>
<p>I've been trying to put my finger on exactly why we see these similarities. I don't think it's intentional. I'm not suggesting that Jon Blow started from Disneyland as his base to work from. Instead, I believe we are seeing an example of <em>convergent evolution</em>.</p>
<p>These games (and Disneyland) have some of the same design constraints. They want a world with as many <em>different things</em> in as possible. They want the smallest space, sometimes because of limited real-estate or limited construction resources, but also to minimize the amount of walking the guest has to do.</p>
<p>More similarities come up as a result of these constraints. You have a small area, and you need to devote it <em>all</em> to guest entertainment. But you still need places for maintenance and behind-the-scenes work. During the construction of Disney World in Florida, they opted to hide all of their maintenance <em>underneath the park</em>. The entire park is built on top of a subterranean layer of tunnels, secretly accessible at the surface via what's known as "Utilidors". You don't have to play The Witness for very long to find that there's some hidden underground secrets there too; little glimpses through holes in the ground, or down a well, provide a peek into the underground system that sits beneath the puzzles.</p>
<p>This leads me to conclude that there must exist some force that drives some video games towards these same design choices:</p>
<div class="admonition theorem">
<p class="admonition-title">Theorem</p>
<p>Any world that tries to pack the most content into the smallest space will eventually become Disneyland.</p>
</div>
<p>It seems like the act of trying to fit as many varied elements into a small space can unconsciously push designs towards this same layout, with an entranceway, hub, dominating features (castle/mountain), and a ring around the edge.</p>
<p>Video games, like Disneyland, aren't built to be real. The castles aren't <em>real</em> castles, the shipwreck isn't a <em>real</em> shipwreck. They're <a href="https://en.wikipedia.org/wiki/Folly">follys</a>; little pieces of architecture to paint a picture without having a particular purpose. This is why we get the same vibes from games like The Witness and experiences like Disneyland. The feeling that the whole thing is designed around <em>us</em> instead of being designed for it's own purposes.</p>
<p>I'll also mention that the Witness also has a hotel for visitors to the island to relax in after their hard day's adventuring. A hotel that, like the real Disneyland, sits outside the park. It's a meta-element, a framing device -- not one that forms part of the main attraction, but one that's necessary for the attraction to function.</p>
<p>Jon Blow has mentioned on several occasions his goal of "no-filler" for his games -- the desire to pack the maximum amount of content into a small package. Does the pursuit of maximizing value in a small area lead to subconscious parallel design decisions for small environments?</p>
<p>I guess I just find it interesting that people tackling similar problems arrive at similar solutions without realizing. Maybe it really is a small world after all.</p>]]></content:encoded>
	</item>
	<item>
		<title>Learning Via Bullshit</title>
		<link>http://www.codersnotes.com/notes/learning-via-bullshit</link>
		<pubDate>
			Tue, 06 Dec 2016 08:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/learning-via-bullshit</guid>
		<content:encoded><![CDATA[<p>There's two ways to learn about something. One is to go in through the front door; you read the tutorial, you follow the instructions, and you progress forward through it.</p>
<p>But the trouble with that approach is that you'll only learn what they want you to learn. Everyone has an agenda, and what they directly tell you about their product only reflects that agenda. If you want to really understand the strengths and tradeoffs of a system, you need to push past that and approach from a different point of view.</p>
<p>I saw a <a href="https://www.youtube.com/watch?v=EaLboOUG9VQ">fantastic talk by Vyacheslav Egorov</a> about LuaJIT and dynamic
languages. I'll quote a big old chunk of it here because I think it deserves
quoting.</p>
<blockquote>
<p><strong>"What I learned from LuaJIT", Vyacheslav Egorov</strong></p>
<p><iframe width="300" height="300" src="https://www.youtube.com/embed/EaLboOUG9VQ" allowfullscreen class="right"></iframe></p>
<p>Some people, after seeing this kind of compiled code, they
will ask, "how does it do it?", and they will try to go and
learn this by reading the source.</p>
<p>And I will tell you that I'm not the kind of person who can
learn things by reading the source from the beginning to the
end, mostly because it's very hard to find a beginning and 
end in a pile of C code.</p>
<p>So instead, I do strange things to the source, like here for example
I add a key to the table which... I say <code>p[1]=1</code> and I just thread it 
through the whole loop iteration. Then I look at what kind of
code the LuaJIT generates, and discover that suddenly there is a whole
pile of assembly coming out. There is a table allocation here and some GC 
steps, and whatnot.</p>
<p>So I like to ask "why does it <em>not</em> do something?", and learning by
fixing bugs, or at least trying to understand why something doesn't work.
And I think this is the much better learning technique. </p>
</blockquote>
<p>Learning why things don't work is often the most valuable way to
really learn the tradeoffs involved in a system. The trouble with many
modern systems though, is that they pretend there <em>are</em> no tradeoffs,
and that there are no flaws. Every system today pretends to be perfect.</p>
<p>The late, great Douglas Adams had this very pertinent quote on the matter:</p>
<blockquote>
<p><strong>Douglas Adams (from Mostly Harmless)</strong></p>
<p>The major difference between a thing that might go wrong and a thing 
that cannot possibly go wrong is that when a thing that cannot possibly 
go wrong goes wrong it usually turns out to be impossible to get at and
repair.</p>
</blockquote>
<p>That's the trouble with a lot of systems. They pretend they're perfect, when they're not. Any engineering project contains both intentional tradeoffs, and unintentional fuckups. I've found over the years that by understanding the dark corners of things, you sometimes gain a greater understanding of the whole thing.</p>
<p>Don't look at what they <em>are</em> telling you, look at what they're not. If someone's trying to promote, oh I don't know, let's say JavaScript, and they say "look here at our benchmark, look how it can rival C in this test" -- don't listen to that. Don't listen to what they <em>do</em> say, listen to what they don't. Don't look at the best benchmarks, look at the worst. Find when something performs the most poorly, and use <em>that</em> to understand it.</p>
<p>Every large software system contains in equal proportions hubris, propaganda, and bullshit. And this is what we really need to study to understand the system. We need to get our hands dirty and poke around in the bullshit, as that's the only place where the truth isn't being hidden.</p>
<p>In Vyacheslav's case above of dynamic language performance, the worst of LuaJIT still holds up well against the best of most other JITs. It can even almost compete with C in some tight loops, but <em>only</em> in those tight loops.</p>
<p>Vyacheslav's example, in case you didn't watch it, shows how LuaJIT can get 
<em>amazing</em> code generation in one case, but then you add just one extra variable,
and suddenly the whole JIT falls apart.</p>
<p>This case is a good example of unexpected consequences - do you really want the performance of your code to change by such a drastic amount just because of adding one extra field? C tends not to have that performance cliff-drop; the performance is directly related to your understanding of the system, which is why it's remained such a popular language for all these years.</p>
<p>Many modern systems don't have that property. Instead, the performance of your typical dynamic language is either a) <em>slow always</em>, or worse: b) <em>slow sometimes</em>. And the <em>sometimes</em> is the killer. The performance of a typical dynamic language is tied directly to Foo. Wait, what? What the hell is Foo? That's just it. It's an unknown. It's something you, as the user, can't predict. You can't design
your software around it, or rely on it for critical operation, because it's an 
unknown that the JIT implementors try to pretend doesn't exist.</p>
<p>If you want to learn C, you might learn more by writing to element 201 of a 200-element array than by reading a thousand tutorials. Many C programmers remember that first time when they didn't initialize a variable and their program failed as a result. But they learned a lot about the language, and the machine, as a consequence of that.</p>
<p>The bugs reveal the truth of what the software is. One of the good things to be said about C++ is that <em>many</em> (not all!) of the bugs happen once when you try to compile something, not later when you run the code. If you're going to have unpredictability, it's better that the unpredictable parts happen to you while you're <em>designing</em> the software, not to some other guy at home using it.</p>
<p>It's fine for systems to have weaknesses, as long as people are honest and up-front about it, because that's how you can understand what a system is really doing. C doesn't pretend to be perfect, it's shitty and makes you take care about fiddly details a lot of the time. But it never hides these things from you. I see so many systems being developed that unfortunately take the approach Douglas Adams lamented -- pretend your system has no faults, and prevent the user from ever being able to understand those faults.</p>]]></content:encoded>
	</item>
	<item>
		<title>Beating The Compiler</title>
		<link>http://www.codersnotes.com/notes/beating-the-compiler</link>
		<pubDate>
			Mon, 28 Nov 2016 08:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/beating-the-compiler</guid>
		<content:encoded><![CDATA[<p>An oft-repeated fact on programming forums these days is that a decent optimizing compiler will always beat a puny human's attempt at hand-written assembler. There are rare cases, like MPEG decoders, where making good use of the SIMD instructions can allow assembly to massively beat the compiler. But generally you'll hear that the compiler will always do better.</p>
<p>The reason given for this is usually that a modern CPU has so many pipelines and instruction hazards to deal with, and a naive assembly routine won't do as good a job dealing with them.</p>
<p>But is it true? Let's not just take some guys word on the Internet as gospel, let's do a little experiment and find out.</p>
<p>We'll just take a simple piece of code to look at here. I'm not going to pick an example that would benefit heavily from exotic intrinsics. Instead I'll just use an old standard, <em>quicksort</em>.</p>
<p>Here's the naive C++ quicksort we'll be testing against:</p>
<div class="codehilite"><pre><span></span><code><span class="k">struct</span> <span class="nc">Item</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">key</span><span class="p">;</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">value</span><span class="p">;</span><span class="w"> </span><span class="p">};</span><span class="w"></span>

<span class="k">extern</span><span class="w"> </span><span class="s">&quot;C&quot;</span><span class="w"> </span>
<span class="kt">void</span><span class="w"> </span><span class="n">sortRoutine</span><span class="p">(</span><span class="n">Item</span><span class="w"> </span><span class="o">*</span><span class="n">items</span><span class="p">,</span><span class="w"> </span><span class="kt">int</span><span class="w"> </span><span class="n">count</span><span class="p">)</span><span class="w"></span>
<span class="p">{</span><span class="w"></span>
<span class="w">    </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">count</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"></span>
<span class="w">        </span><span class="k">return</span><span class="p">;</span><span class="w"> </span><span class="c1">// already sorted if only zero/one element</span>

<span class="w">    </span><span class="c1">// Pick the pivot.</span>
<span class="w">    </span><span class="n">Item</span><span class="w"> </span><span class="n">pivot</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">items</span><span class="p">[</span><span class="n">count</span><span class="mi">-1</span><span class="p">];</span><span class="w"></span>
<span class="w">    </span><span class="kt">int</span><span class="w"> </span><span class="n">low</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w"></span>
<span class="w">    </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kt">int</span><span class="w"> </span><span class="n">pos</span><span class="o">=</span><span class="mi">0</span><span class="p">;</span><span class="n">pos</span><span class="o">&lt;</span><span class="n">count</span><span class="mi">-1</span><span class="p">;</span><span class="n">pos</span><span class="o">++</span><span class="p">)</span><span class="w"></span>
<span class="w">    </span><span class="p">{</span><span class="w"></span>
<span class="w">        </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">items</span><span class="p">[</span><span class="n">pos</span><span class="p">].</span><span class="n">key</span><span class="w"> </span><span class="o">&lt;=</span><span class="w"> </span><span class="n">pivot</span><span class="p">.</span><span class="n">key</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w"></span>
<span class="w">            </span><span class="c1">// swap elements</span>
<span class="w">            </span><span class="n">Item</span><span class="w"> </span><span class="n">tmp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">items</span><span class="p">[</span><span class="n">pos</span><span class="p">];</span><span class="w"></span>
<span class="w">            </span><span class="n">items</span><span class="p">[</span><span class="n">pos</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">items</span><span class="p">[</span><span class="n">low</span><span class="p">];</span><span class="w"></span>
<span class="w">            </span><span class="n">items</span><span class="p">[</span><span class="n">low</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tmp</span><span class="p">;</span><span class="w"></span>

<span class="w">            </span><span class="n">low</span><span class="o">++</span><span class="p">;</span><span class="w"></span>
<span class="w">        </span><span class="p">}</span><span class="w"></span>
<span class="w">    </span><span class="p">}</span><span class="w"></span>

<span class="w">    </span><span class="n">items</span><span class="p">[</span><span class="n">count</span><span class="mi">-1</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">items</span><span class="p">[</span><span class="n">low</span><span class="p">];</span><span class="w"></span>
<span class="w">    </span><span class="n">items</span><span class="p">[</span><span class="n">low</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pivot</span><span class="p">;</span><span class="w"></span>

<span class="w">    </span><span class="n">sortRoutine</span><span class="p">(</span><span class="n">items</span><span class="p">,</span><span class="w"> </span><span class="n">low</span><span class="p">);</span><span class="w"></span>
<span class="w">    </span><span class="n">sortRoutine</span><span class="p">(</span><span class="n">items</span><span class="o">+</span><span class="n">low</span><span class="o">+</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">count</span><span class="mi">-1</span><span class="o">-</span><span class="n">low</span><span class="p">);</span><span class="w"></span>
<span class="p">}</span><span class="w"></span>
</code></pre></div>

<p>It's nothing fancy. It's not the best sorting algorithm in the world, and this isn't even the best implementation of it, but it's simple and it'll do just fine.</p>
<p>Now let's try a direct naive assembly implementation of it:</p>
<div class="codehilite"><pre><span></span><code><span class="nl">sortRoutine:</span>
    <span class="c1">; rcx = items</span>
    <span class="c1">; rdx = count</span>
    <span class="nf">sub</span> <span class="nb">rdx</span><span class="p">,</span> <span class="mi">1</span>
    <span class="nf">jbe</span> <span class="nv">done</span>

    <span class="c1">; Pick the pivot.</span>
    <span class="nf">mov</span> <span class="nb">r8</span><span class="p">,</span> <span class="p">[</span><span class="nb">rcx</span><span class="o">+</span><span class="nb">rdx</span><span class="o">*</span><span class="mi">8</span><span class="p">]</span> <span class="c1">; r8 = pivot data</span>
    <span class="nf">xor</span> <span class="nb">r9</span><span class="p">,</span> <span class="nb">r9</span>          <span class="c1">; r9 = low</span>
    <span class="nf">xor</span> <span class="nb">r10</span><span class="p">,</span> <span class="nb">r10</span>        <span class="c1">; r10 = pos</span>
<span class="nl">partition:</span>
    <span class="nf">cmp</span> <span class="p">[</span><span class="nb">rcx</span><span class="o">+</span><span class="nb">r10</span><span class="o">*</span><span class="mi">8</span><span class="p">],</span> <span class="nb">r8d</span>
    <span class="nf">jg</span> <span class="nv">noswap</span>

    <span class="c1">; swap elements</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="p">[</span><span class="nb">rcx</span><span class="o">+</span><span class="nb">r10</span><span class="o">*</span><span class="mi">8</span><span class="p">]</span>
    <span class="nf">mov</span> <span class="nb">r11</span><span class="p">,</span> <span class="p">[</span><span class="nb">rcx</span><span class="o">+</span><span class="nb">r9</span><span class="o">*</span><span class="mi">8</span><span class="p">]</span>
    <span class="nf">mov</span> <span class="p">[</span><span class="nb">rcx</span><span class="o">+</span><span class="nb">r9</span><span class="o">*</span><span class="mi">8</span><span class="p">],</span> <span class="nb">rax</span>
    <span class="nf">mov</span> <span class="p">[</span><span class="nb">rcx</span><span class="o">+</span><span class="nb">r10</span><span class="o">*</span><span class="mi">8</span><span class="p">],</span> <span class="nb">r11</span>
    <span class="nf">inc</span> <span class="nb">r9</span>

<span class="nl">noswap:</span>
    <span class="nf">inc</span> <span class="nb">r10</span>
    <span class="nf">cmp</span> <span class="nb">r10</span><span class="p">,</span> <span class="nb">rdx</span>
    <span class="nf">jb</span> <span class="nv">partition</span>

    <span class="c1">; move pivot into place</span>
    <span class="nf">mov</span> <span class="nb">rax</span><span class="p">,</span> <span class="p">[</span><span class="nb">rcx</span><span class="o">+</span><span class="nb">r9</span><span class="o">*</span><span class="mi">8</span><span class="p">]</span>
    <span class="nf">mov</span> <span class="p">[</span><span class="nb">rcx</span><span class="o">+</span><span class="nb">rdx</span><span class="o">*</span><span class="mi">8</span><span class="p">],</span> <span class="nb">rax</span>
    <span class="nf">mov</span> <span class="p">[</span><span class="nb">rcx</span><span class="o">+</span><span class="nb">r9</span><span class="o">*</span><span class="mi">8</span><span class="p">],</span> <span class="nb">r8</span>

    <span class="c1">; recurse</span>
    <span class="nf">sub</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nb">r9</span>
    <span class="nf">lea</span> <span class="nb">rax</span><span class="p">,</span> <span class="p">[</span><span class="nb">rcx</span><span class="o">+</span><span class="nb">r9</span><span class="o">*</span><span class="mi">8</span><span class="o">+</span><span class="mi">8</span><span class="p">]</span>
    <span class="nf">push</span> <span class="nb">rax</span>
    <span class="nf">push</span> <span class="nb">rdx</span>
    <span class="nf">mov</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nb">r9</span>
    <span class="nf">call</span> <span class="nv">sortRoutine</span>
    <span class="nf">pop</span> <span class="nb">rdx</span>
    <span class="nf">pop</span> <span class="nb">rcx</span>
    <span class="nf">test</span> <span class="nb">rdx</span><span class="p">,</span> <span class="nb">rdx</span>
    <span class="nf">jnz</span> <span class="nv">sortRoutine</span>

<span class="nl">done:</span>
    <span class="nf">ret</span>
</code></pre></div>

<p>It was quite easy to write this, largely due to Intel's flexible memory addressing operators. What's interesting is that I made no real attempt to pay attention to scheduling, pipelining, etc. I just wrote it out as simple assembly.</p>
<p>Now let's time it. I wrote a simple test harness that sorts a 1000000-item array. I run the test 100 times and take the best-case across the whole set. I'll compile the C++ version with gcc 4.8.1, clang 3.8.0, and MSVC 2013.</p>
<h3 id="results">Results</h3>
<div class="codehilite"><pre><span></span><code>sort_cpp_recurse_gcc.exe      : Took 99ms best-case across 100 runs
sort_cpp_recurse_clang.exe    : Took 99ms best-case across 100 runs
sort_cpp_recurse_ms.exe       : Took 98ms best-case across 100 runs
sort_asm_recurse.exe          : Took 92ms best-case across 100 runs
</code></pre></div>

<p>Well that's interesting. The different compilers did mostly around the same, with MSVC having a slight edge. <strong>But the assembly version ran fastest</strong>, being a good 7% faster in this case.</p>
<p>Now the thing about C++ is that it's not always a good representation of the underlying machine. It's fine when it comes to variables, but it's representation of the stack is very limited. C++ pretends we can only use the stack as a call stack, whereas in reality one of the things we can do is to use it as a <em>data</em> stack instead.</p>
<p>So let's try that and see what happens. We'll remove the recursive calls to sortRoutine, and instead push/pop our data ranges directly from the stack. This allows us to run in a single loop without having to actually recurse. This can often have a strong benefit because it removes the overhead of entering/exiting the function each time.</p>
<p>I won't post the code for it here, but it's in the zipfile below if you want to see it.</p>
<div class="codehilite"><pre><span></span><code>sort_cpp_recurse_gcc.exe      : Took 99ms best-case across 100 runs
sort_cpp_recurse_clang.exe    : Took 99ms best-case across 100 runs
sort_cpp_recurse_ms.exe       : Took 98ms best-case across 100 runs
sort_asm_recurse.exe          : Took 92ms best-case across 100 runs
sort_cpp_iter_gcc.exe         : Took 106ms best-case across 100 runs
sort_cpp_iter_clang.exe       : Took 97ms best-case across 100 runs
sort_cpp_iter_ms.exe          : Took 95ms best-case across 100 runs
sort_asm_iter.exe             : Took 92ms best-case across 100 runs
</code></pre></div>

<p>Hmm. The assembly version comes out almost the same. I suspect this is because while an iterative approach removes the function-setup overhead, our hand-written x64 version doesn't actually <em>have</em> much function-setup overhead, so doesn't really benefit.</p>
<p>But for the C++ versions, it's a different story. Most of them got a slight speedup, but gcc is actually slower! As far as I can tell from looking at the disassembly, it seems like it's managed to out-clever itself. The increased control paths and things for it to consider have given it too many balls to keep in the air at once.</p>
<p>I compiled these tests on x64, where the default calling convention is fastcall. I suspect that if compiled for 32-bit instead, using the cdecl stack-based convention, the non-recursive version would have done better relatively. I didn't try it though, I'll leave that as an exercise to the reader.</p>
<h3 id="conclusion">Conclusion</h3>
<p>So it seems like the old "modern compilers are always faster than you" spiel is not necessarily true. What <em>is</em> true however, is that the compiler did a <em>good enough</em> job, and the code is easier to work with. So while you might be able to squeeze a little more speed out, it's probably not worth the maintenance hassle.</p>
<p>The assembly version <em>was</em> faster though. I suppose if there's anything to be learned here, it's that people on the Internet <em>may sometimes be full of shit</em>.</p>
<div class="admonition download">
<p class="admonition-title">Download</p>
<p><a href="beating-the-compiler/sorttest.zip">sorttest.zip</a> - All the code used for this article.</p>
</div>]]></content:encoded>
	</item>
	<item>
		<title>The Illusion Of Controls</title>
		<link>http://www.codersnotes.com/notes/controls</link>
		<pubDate>
			Sat, 15 Oct 2016 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/controls</guid>
		<content:encoded><![CDATA[<p><img alt="" src="controls/goldberg.gif#right"></p>
<p>Some things are just plain hard to use. There's a lot of things you have to learn before you can use it effectively, there's big manuals you have to read, there's gotchas you need to be aware of first.</p>
<p>I can't use this thing, people will say. I just want to do X, why do I have to mess around with all these details which are getting in the way? Why can't it be simple?</p>
<p>It's a common enough complaint, one you'll hear directed against anything from the Linux command-line through to the user interface of Dwarf Fortress.</p>
<p>But for every complicated interface, there's always someone who'll reply with the common phrase:</p>
<blockquote>
<p>"X <em>needs</em> to be that complicated. Y is fine for noobs, but with X you get so much more <em>control</em>."</p>
</blockquote>
<p>And herein lies the problem. The illusion of controls. It's not often that one letter can make such a difference, but what we're talking about here is <em>control</em> vs <em>control<strong>s</strong></em>.</p>
<p>Whenever a problem is presented, all good programmers know to head directly for a good <em>car analogy</em>. It's a tried-and-tested method we've used for years which I'm almost certainly sure won't backfire on me terribly. Nope. Here we go!</p>
<p>I'll quote from these instructions on how to drive a Model-T Ford, an experience once described by Top Gear's Jeremy Clarkson as "the hardest thing in the world", like trying to pat your head and rub your belly at the same time.</p>
<blockquote>
<p><strong> <a href="http://modelt.ca/how-to-drive/">How To Drive a Model-T Ford</a> </strong></p>
<p>There are three pedals on the floor marked from left to right when sitting in the driver's seat: C (clutch), R (reverse) and B (break). There are two levers on the steering column, spark advance and throttle, and one floor lever to the left of the driver. The floor lever is neutral while in the upright position, second gear when in the forward position while the leftmost pedal (C) is not depressed, and emergency brake when all the way back.</p>
<p>All speeds are controlled by a foot pedal enabling the driver to stop, start, change speeds, or reverse the car without removing the hands from the steering wheel. The foot pedal at the right, operates the brake on the transmission. The pedal in the center, operates the reverse. The left foot pedal, is the control lever acting on the clutch.</p>
<p>The hand lever when thrown forward engages high speed; when pulled back, operates the emergency brake. The lever is in neutral when almost vertical and clutch is in a released condition. With the hand lever thrown forward in high speed, a light pressure on pedal 'C' releases the clutch while a full pressure on the pedal throws into slow speed; by gradually releasing the pedal, it will come back through neutral into high speed.</p>
</blockquote>
<p>There's more -- you've also got the "spark advance" lever (no idea), a carburetor adjustment, and an additional throttle lever.</p>
<p>On the other end of the spectrum is something like a bicycle. On a bicycle you have pedals for your speed, and handlebars to steer. That's basically it, there's a brake lever and maybe a gear selector. It's an incredibly simple machine though, one which you can learn without instruction very quickly.</p>
<p>Part of the simplicity of the bicycle is that you can <em>see</em> how it works. It's immediately obvious how your action on the pedals affects the ground speed. You can directly see the relationship between the brake line and the wheel.</p>
<p>The difference is a bicycle has <em>control</em>. The Model-T has <em>controls</em>. With a bicycle every part of your body is in direct connection with the movement. You can <em>lean</em> into corners, shift your weight around. You can <em>feel</em> the brakes and whether you're applying the right pressure.</p>
<p>The Model-T takes the approach of having <em>controls</em>. A complex beast of a machine that requires memorization, and the knowledge of what each control does and how it operates the beast. Modern cars try to simplify that as much as possible, and cars like the Tesla go to an extreme, having not even a clutch or gearbox. Perhaps it's not the best parallel, and I'm sure some reader will call me out on my terrible automotive knowledge. But the point remains valid, and programmers would do well to heed it.</p>
<p>An Etch-a-Sketch has more controls than a paintbrush, but has no control. Give an artist a paintbrush and it becomes an extension of him, a tool he can use to apply different pressure, to <em>feel</em> the paint as he moves it around a canvas. An operating system like Linux gives you a lot of controls -- a hundred different config files to adjust, fontconfigs to manage, but it gives you no <em>control</em>. We spend so long caught in a Byzantine complex of configurations and dotfiles that we fool ourselves into thinking that the controls were the reason we originally came here.</p>
<p>And for the record, I don't feel the solution is to just <em>hide</em> the complexity like so many programs do (I'm looking at you, Apple). That's like putting the controls inside a sealed box and hoping you won't try and adjust them. We need more systems like the Tesla and its all-electric drivetrain, where the need for controls dissolves away.</p>]]></content:encoded>
	</item>
	<item>
		<title>The Challenge Of Making Things</title>
		<link>http://www.codersnotes.com/notes/challenge-of-making-things</link>
		<pubDate>
			Tue, 04 Oct 2016 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/challenge-of-making-things</guid>
		<content:encoded><![CDATA[<p><a href=https://www.reddit.com/r/gaming/comments/55lyxc/ive_been_building_this_minecraft_map_for_45_years>
<img alt="" src="challenge-of-making-things/minecraft.jpg#right">
</a></p>
<p>What would you do if you could do <em>anything</em>? If you were all-powerful, and could create anything just by waving your hands around? The answer is, nothing.</p>
<p>You could create anything you want <em>right now</em>. Just grab a pen and paper and draw a new universe. You could have drawn 5 different scenes today, but you didn't. It takes a special kind of person to push past the barrier of the empty page, a talent I and a large majority have trouble with.</p>
<p>An unrestricted blank canvas is the worst possible killer of creativity. People build models of Game Of Thrones worlds in Minecraft. Why? They could build it in Autodesk Maya, or Sketchup, and it'd look better (and might even be easier for a large scene). The restrictions breed creativity. It's not enough to just make something, you need a frame to place it within. Artists need a frame to define the medium they work within.</p>
<p>Why do people build a working 6502 using Minecraft redstone? I mean if building a 6502 is the goal, why not use a better medium? Perhaps this shows us that the subject itself is not as important as the medium it's made in.</p>
<p>Retro games were originally developed in a constrained medium, and required great effort on the part of the designers to fit the game into that. Now we have gigahertz CPUs and GPUs, but people still make pixel-art games and text adventures. In a world where Unity provides instant access to a professional quality 3D scene editor, why would someone make games in PuzzleScript?</p>
<p>We need mediums. An artist with no restrictions will never make anything. Some people think retro games are a fad, but I think as technology gets broader we're going to look to the narrow canvas ever more so.</p>
<p>I worry about things like Dreams, which promises an all-powerful blank canvas. I think a large part of Little Big Planet's success is that you couldn't make <em>everything</em>. It limited you to a simplified 2D canvas of mechanisms, but people had fun trying to push those limits. If there are no limits, what can you push?</p>]]></content:encoded>
	</item>
	<item>
		<title>Untonemapping, and other stupid tricks</title>
		<link>http://www.codersnotes.com/notes/untonemapping</link>
		<pubDate>
			Sun, 02 Oct 2016 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/untonemapping</guid>
		<content:encoded><![CDATA[<p>I've been meaning to write something about this for years but never got around to it. I don't claim there's any great use for this stuff; it's just one of those little oddities us graphics programmers like to collect.</p>
<p>You all know what tonemapping is - converting a HDR (High Dynamic Range) image into an LDR (Low Dynamic Range) image for display. What might not be immediately obvious is that it's reversible.</p>
<p>We can formalize this relationship using the following notation:</p>
<div class="codehilite"><pre><span></span><code>L(x) = 1 - exp2(-k*x)
</code></pre></div>

<p>That's the standard formula for an exponential tone mapper. There's a lot of other functions you can use (Reinhard etc) but for the purposes of today's article it doesn't matter, so let's just pick the simplest one to work with. For <em>final display</em> of course it may well matter, but we're not talking about final display here. The reason it doesn't matter is that it <em>cancels out</em>.</p>
<p>Note that I'll always be using exp2, not exp/log/ln etc, and you should too. GPUs often only support exp2, with the others requiring an extra multiply to convert bases. So if we work in base 2 ourselves we can save that multiply.</p>
<p>So if the formula above is tonemapping, what's untonemapping? Well it's just a simple inverse:</p>
<div class="codehilite"><pre><span></span><code>H(x) = log2(1 - x)/-k
</code></pre></div>

<p>Ok so far. But what use is it? Let's try an example.</p>
<p>Let's say you want to render a nice image of a wooden teapot (hey why not). So you make a beautiful Photoshop image, like so:</p>
<p>
<div class="caption"><img alt="" src="untonemapping/wood.jpg" title="Our source texture."><p>Our source texture.</p>
</div>
</p>
<p>Then you slap it on a basic lit mesh. First let's compare how it looks when you render it using an old LDR engine, then using a standard HDR engine with tonemapping:</p>
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div class="caption"><a href="untonemapping/ldr.png#thumb"><img alt="" src="untonemapping/ldr.thumb.png#thumb" title="Old-school LDR engine."></a><p>Old-school LDR engine.</p>
</div>
</td>
<td>
<div class="caption"><a href="untonemapping/bad_hdr.png#thumb"><img alt="" src="untonemapping/bad_hdr.thumb.png#thumb" title="Modern HDR engine."></a><p>Modern HDR engine.</p>
</div>
</td>
</tr>
</tbody>
</table>
<div class="codehilite"><pre><span></span><code><span class="c1">// LDR:</span>
<span class="n">float3</span><span class="w"> </span><span class="n">diffuse</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tex2D</span><span class="p">(</span><span class="n">diffuseTex</span><span class="p">,</span><span class="w"> </span><span class="n">uv</span><span class="p">).</span><span class="n">rgb</span><span class="p">;</span><span class="w"></span>
<span class="n">float3</span><span class="w"> </span><span class="n">color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">diffuse</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">lighting</span><span class="p">;</span><span class="w"></span>
<span class="k">return</span><span class="w"> </span><span class="n">color</span><span class="p">;</span><span class="w"> </span><span class="c1">// no tonemap</span>

<span class="c1">// HDR:</span>
<span class="n">float3</span><span class="w"> </span><span class="n">diffuse</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tex2D</span><span class="p">(</span><span class="n">diffuseTex</span><span class="p">,</span><span class="w"> </span><span class="n">uv</span><span class="p">).</span><span class="n">rgb</span><span class="p">;</span><span class="w"></span>
<span class="n">float3</span><span class="w"> </span><span class="n">color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">diffuse</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">lighting</span><span class="p">;</span><span class="w"></span>
<span class="kt">float</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2.0f</span><span class="p">;</span><span class="w"></span>
<span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">exp2</span><span class="p">(</span><span class="n">color</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">-</span><span class="n">k</span><span class="p">);</span><span class="w"> </span><span class="c1">// exponential tonemap</span>
</code></pre></div>

<p>Eurgh. Both of these images kinda suck. Our texture looked so nice in Photoshop, but now it's been distorted in <em>both</em> renderings. The LDR one preserves the vibrant orange colors well, but because it's an LDR engine it can't light the thing properly, and clips the colors badly.</p>
<p>However, the HDR engine has captured the full lighting range, but at the expense of draining the contrast and saturation from the texture. This does depend on which tonemapping curve you use, some fare better than others. But they all tend to exhibit this problem. Why is this?</p>
<p>The problem is that we're using this photo as a diffuse map, but it <em>isn't a diffuse map</em>. What the photo really is, is the output of another renderer. (In this case, the renderer was the real world and a camera)</p>
<p>This means the source photo is <em>already tonemapped</em>. We need to reverse the process to recover the original diffuse map. We can do this by assuming the photo was taken under some standardized lighting conditions, and simply running it through the untonemapping operator.</p>
<p>But, you ask, how can I untonemap it if I don't know the value of k to use? That's the cool part: it doesn't matter. Just pick one (1.0 works well). That'll be our reference exposure value. The exposure values we then use to render our scene will then be defined relative to our base.</p>
<div class="codehilite"><pre><span></span><code><span class="c1">// HDR using untonemapping to correct the diffuse texture</span>
<span class="n">float3</span><span class="w"> </span><span class="n">diffuse</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tex2D</span><span class="p">(</span><span class="n">diffuseTex</span><span class="p">,</span><span class="w"> </span><span class="n">uv</span><span class="p">).</span><span class="n">rgb</span><span class="p">;</span><span class="w"></span>
<span class="kt">float</span><span class="w"> </span><span class="n">k</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">2.0f</span><span class="p">;</span><span class="w"></span>
<span class="n">diffuse</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">-</span><span class="n">log2</span><span class="p">(</span><span class="mi">1</span><span class="o">-</span><span class="n">diffuse</span><span class="p">);</span><span class="w"> </span><span class="c1">// untonemap</span>
<span class="n">color</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">diffuse</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">lighting</span><span class="p">;</span><span class="w"></span>
<span class="k">return</span><span class="w"> </span><span class="mi">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">exp2</span><span class="p">(</span><span class="n">color</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="o">-</span><span class="n">k</span><span class="p">);</span><span class="w"> </span><span class="c1">// tonemap</span>
</code></pre></div>

<p>So how does that look now?</p>
<p>
<div class="caption"><a href="untonemapping/good_hdr.png#thumb"><img alt="" src="untonemapping/good_hdr.thumb.png#thumb" title="HDR engine using untonemapping."></a><p>HDR engine using untonemapping.</p>
</div>
</p>
<p>Well that's a lot better. It now matches the source map <em>exactly</em> - the output of our renderer is identical to the artists image, and we now have a good mathematical framework for taking our output results and working on them.</p>
<p>Before we go any further I'm going to make one small but important tweak. There's a lot of "1-" going on here, and it's kinda annoying. Let's get rid of it. We don't need it.</p>
<div class="codehilite"><pre><span></span><code>L(x) = exp2(-k*x)
H(x) = log2(x)/-k
</code></pre></div>

<p>This means all our LDR images will be inverted, but we can just flip it back before display. I'll call this space <strong>inverted-LDR</strong>, and that's what I'll be using for the rest of the article.</p>
<p>This now means that in LDR space, black represents infinitely bright. This turns out to be surprisingly useful. In fact, it makes me wonder if that isn't in fact the natural image representation we should all use by default.</p>
<h3 id="and-now-for-my-next-trick">And now for my next trick</h3>
<p>So what are the consequences of this? Well, now that we have a more rigorous definition of how to convert to/from LDR space, we can convert some common HDR operations so that they work in LDR space directly.</p>
<p>So, for instance. In HDR space, if you want to add two colors together, you just add them. Let's write that out:</p>
<div class="codehilite"><pre><span></span><code>Ah(x, y) = x+y
</code></pre></div>

<p>We can get the LDR equivalent by tone mapping it:</p>
<div class="codehilite"><pre><span></span><code>Al(x, y) = L(Ah(x, y))
</code></pre></div>

<p>Expanding that out:</p>
<div class="codehilite"><pre><span></span><code>Al(x, y) = L(x+y)
Al(x, y) = exp2(-k*(x+y))
= exp2(-k*x + -k*y)
</code></pre></div>

<p>Now here's the trick. We can use the laws of logarithms to split that apart:</p>
<div class="codehilite"><pre><span></span><code>= exp2(-k*x) * exp2(-k*y)
</code></pre></div>

<p>Do you see what's happened here? It's equivalent to tone mapping the two colors individually, then multiplying them. Just to spell that out for you:</p>
<p>Given two inverted-LDR images, you add them together by just <strong>multiplying them</strong>.</p>
<div class="codehilite"><pre><span></span><code>ADDinv(x, y) = x * y
</code></pre></div>

<p>What would happen if we were using regular-LDR instead of inverted-LDR? Let's write it out with the 1-x's in:</p>
<div class="codehilite"><pre><span></span><code><span class="n">ADDreg</span><span class="p">(</span><span class="n">x</span><span class="p">,</span> <span class="n">y</span><span class="p">)</span> <span class="o">=</span> <span class="mh">1</span><span class="o">-</span><span class="p">((</span><span class="mh">1</span><span class="o">-</span><span class="n">x</span><span class="p">)</span><span class="o">*</span><span class="p">(</span><span class="mh">1</span><span class="o">-</span><span class="n">y</span><span class="p">))</span>
</code></pre></div>

<p>Oh look, that's the Photoshop 'screen' blend mode. I don't know if that's something the Photoshop designers intentionally thought of; if not, it's certainly an interesting co-incidence.</p>
<h3 id="but-wait-theres-more">But wait! There's more!</h3>
<p>That's addition taken care of. What about multiply?</p>
<p>In HDR-space, a multiply looks like this:</p>
<div class="codehilite"><pre><span></span><code>Mh(x, y) = x * y
</code></pre></div>

<p>We can do the same tricks as before. First let's tonemap it to get it into LDR.</p>
<div class="codehilite"><pre><span></span><code>Ml(x, y) = L(Mh(x, y))
Ml(x, y) = L(x*y)
Ml(x, y) = exp2(-k*x*y)
</code></pre></div>

<p>And then apply logarithms to split apart again:</p>
<div class="codehilite"><pre><span></span><code>Ml(x, y) = exp2(-k*x)^y
</code></pre></div>

<p>What does this mean? It means that if you have an inverted-LDR image, and a HDR image, you can multiply those together by raising the LDR image to the power of the HDR one.</p>
<p>e.g.</p>
<div class="codehilite"><pre><span></span><code>MULinv(xl, yh) = xl^yh
</code></pre></div>

<h3 id="an-example">An Example</h3>
<p>Here's an example of how you might throw all this together. Let's imagine you're starting with an inverted-LDR diffuse texture, and you want to do some HDR lighting with it. We can use the "multiply" rule to do the diffuse lighting, then the "add" rule to add on the specular lighting. Note that the diffuse texture remains in inverted-LDR space throughout, and the final result needs no tonemapping, because it is already in LDR space.</p>
<div class="codehilite"><pre><span></span><code><span class="n">float3</span><span class="w"> </span><span class="n">diffuse</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">tex2D</span><span class="p">(</span><span class="n">diffuseTex</span><span class="p">,</span><span class="w"> </span><span class="n">uv</span><span class="p">).</span><span class="n">rgb</span><span class="p">;</span><span class="w"></span>
<span class="n">float3</span><span class="w"> </span><span class="n">diff_lighting</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">calculateHdrDiffuseLighting</span><span class="p">();</span><span class="w"></span>
<span class="n">float3</span><span class="w"> </span><span class="n">spec_lighting</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">calculateHdrSpecularLighting</span><span class="p">();</span><span class="w"></span>
<span class="n">float3</span><span class="w"> </span><span class="n">ldr_output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">pow</span><span class="p">(</span><span class="n">diffuse</span><span class="p">,</span><span class="w"> </span><span class="n">diff_lighting</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">tonemap</span><span class="p">(</span><span class="n">spec_lighting</span><span class="p">);</span><span class="w"></span>
</code></pre></div>

<p>I'll summarize the inverted-LDR-space rules in a table here:</p>
<table>
<thead>
<tr>
<th>Rule</th>
<th>Formula</th>
</tr>
</thead>
<tbody>
<tr>
<td>HDR to LDR</td>
<td>exp2(-k*x)</td>
</tr>
<tr>
<td>LDR to HDR</td>
<td>log2(x)/-k</td>
</tr>
<tr>
<td>HDR + HDR</td>
<td>x*y</td>
</tr>
<tr>
<td>LDR * HDR</td>
<td>x^y</td>
</tr>
</tbody>
</table>
<p>So there it is. As I said, I don't know if this is going to be especially useful to anyone, but I thought it was interesting how you can do mathematics in LDR-space and yet get the correct results of HDR lighting.</p>]]></content:encoded>
	</item>
	<item>
		<title>Debunking Euclideon&#39;s Unlimited Detail Tech</title>
		<link>http://www.codersnotes.com/notes/euclideon-explained</link>
		<pubDate>
			Tue, 13 Sep 2016 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/euclideon-explained</guid>
		<content:encoded><![CDATA[<iframe width="300" height="300" src="https://www.youtube.com/embed/4uYkbXlgUCw"
frameborder="0" allowfullscreen class="left"></iframe>

<p>Uh oh. They're at it again. Yes folks, <a href="https://www.youtube.com/watch?v=4uYkbXlgUCw">Euclideon are back</a> with more of their smarmy-voice-over-without-any-detail brand of hype. They call it "Unlimited Detail", but what they <em>don't</em> do is explain how any of it actually works.</p>
<p>If only there were some way we could find out how their idea works. If only... wait! There is!</p>
<p>One of the great things about ideas is that you have two choices; you can either keep it a secret, but then you risk someone else coming up with it too. Or, you can <em>patent</em> it, which grants ownership of the idea. Of course, in order to be granted a patent, you need to actually <em>explain</em> what your idea is and how it works.</p>
<p>With that in mind, it's easy to actually find out how the Euclideon tech works. Off we go to the <a href="https://www.ipaustralia.gov.au/">Australia Patent Office</a>! A quick search for Euclideon reveals a number of documents, but there's one <a href="euclideon-explained/patent.pdf">2012390266, "A computer graphics method for rendering three dimensional scenes"</a> that seems to be the one we need.</p>
<p>It's not an especially exciting read, most patents aren't. I'll summarize the description here:</p>
<ol>
<li>The scene is stored as a number of objects.</li>
<li>Most objects are rendered using the fast orthographic method.</li>
<li>Objects up close are rendered using the slow perspective method.</li>
</ol>
<p>
<div class="caption right"><a href="euclideon-explained/octree.jpg#thumb#right"><img alt="" src="euclideon-explained/octree.thumb.jpg#thumb#right" title="Oh look, it's just voxels in an octree."></a><p>Oh look, it's just voxels in an octree.</p>
</div>
</p>
<p>But what is the orthographic method, you ask? Well it turns out not to be that complex. Here it is folks. Prepare yourself for the wonder of the Unlimited Detail Engine:</p>
<ul>
<li><strong>You store colors in octree cells.</strong></li>
<li><strong>You walk recursively over this octree and splat each point on screen.</strong></li>
</ul>
<p>Wait, is that <em>it</em>? Yes my friends, this is the same algorithm described in the 1985 paper <a href="euclideon-explained/voxel-btf.pdf">"Back to-Front Display of Voxel Based Objects"</a>, by Frieder et al. I think Euclideon choose to go front-to-back instead, and use a mask to avoid overdraw, but it's the same thing. They're taking 30 year old technology and passing it off as being next-gen.</p>
<p>What this means is that their data is stored in a pre-built octree. Despite their recent claims, there's <em>no way</em> this can animate like modern games need. The only way you can animate it is if you use <em>stop motion</em> - i.e. have several pre-built octrees and switch between them. And looking at their recent footage, I think that's what they're doing. It all looks kinda... well... jerky?</p>
<p>We can do a little math and run the numbers here. Let's imagine you've got a 3GHz CPU, and you want to render 1000x1000 at 60FPS. That's a million pixels you need to fill in. 3GHz/60=50,000,000 cycles available per frame. Therefore you need to render one pixel in <strong>50</strong> cycles. That's pretty tight. It <em>might</em> be do-able, but then you've just used <em>all</em> of your CPU budget doing it. What about the rest? Do you want anti-aliasing? Lighting? Shadows? Bloom? Depth of field? Well tough, because you've already pegged your CPU out at 100% just filling in the color buffer.</p>
<p>
<div class="caption left"><a href="euclideon-explained/carter.jpg#thumb#left"><img alt="" src="euclideon-explained/carter.thumb.jpg#thumb#left" title="Extreme draw distance in The Vanishing Of Ethan Carter"></a><p>Extreme draw distance in The Vanishing Of Ethan Carter</p>
</div>
</p>
<p>I'm not saying voxel-based games can't work, I think there's definitely a place for less polygony techniques in future. But this isn't it. The trouble with Euclideon is that they spend such a large amount of their time trying to explain that their tech is better than current existing games, when the simple fact is that it <em>isn't</em>. In <a href="https://www.youtube.com/watch?v=4uYkbXlgUCw">their latest video</a> they moan about LOD pops in games. I suggest they go take a look at some <em>actual</em> games. I just finished playing through the delightful <a href="http://www.theastronauts.com/2015/09/the-vanishing-of-ethan-carter-redux-out-now">"Vanishing Of Ethan Carter"</a>, and guess what? No LOD pops <em>anywhere</em> in the game. It draws trees off to the horizon and they all just magically morph to lower-detail versions without you ever noticing.</p>
<p>You might be impressed by their up-close dirt rendering, but it's no match for the current round of games and GPUs. Take a look at "Star Wars: Battlefront" here - that's what we're doing <em>right now</em> using just regular GPUs. It's already light years ahead of their tech. Advances like geometry tessellation have taken polygon rendering to new extremes.</p>
<p>
<div class="caption"><img alt="" src="euclideon-explained/endor.jpg" title="Close-up detail in Star Wars: Battlefront"><p>Close-up detail in Star Wars: Battlefront</p>
</div>
</p>
<p>
<div class="caption right"><a href="euclideon-explained/lowres.jpg#thumb#right"><img alt="" src="euclideon-explained/lowres.thumb.jpg#thumb#right" title="Visible voxel artifacts in a so-called Unlimited Detail engine."></a><p>Visible voxel artifacts in a so-called Unlimited Detail engine.</p>
</div>
</p>
<p>This tech, at least the way they're doing it, is dead. They have <em>no</em> real lighting, none. Just look at their images - it's just N-dot-L, which has been prebaked. I spotted a shadow underneath one of the fences, but oh look, it casts directly downwards. Do you know why? It's because if it cast at an angle, it would spill over onto adjacent objects and prevent re-use of instances. You could argue that they could prebake very nice GI lighting, but they can't; the only way they can get their "unlimited detail" is by instancing the same objects several times.</p>
<p>If you want to see some <em>real</em> exciting advances in point-based technology, go look at the upcoming game <a href="https://www.youtube.com/watch?v=hNSH1vKOK9o">Dreams by Media Molecule</a>. Those guys are way ahead of Euclideon, and guess what? Their stuff doesn't rely on pre-baked hierarchies, it's all genuinely real-time.</p>
<hr>
<p>tl;dr -- GPUs get better every year. If you want unlimited detail, just go buy a PS4 today. But please, don't give these hacks any money.</p>]]></content:encoded>
	</item>
	<item>
		<title>Learning To Wrangle Half-Floats</title>
		<link>http://www.codersnotes.com/notes/wrangling-halfs</link>
		<pubDate>
			Sat, 10 Sep 2016 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/wrangling-halfs</guid>
		<content:encoded><![CDATA[<p>You all know what <a href="http://www.mrob.com/pub/math/floatformats.html">floating-point arithmetic is</a>, so I won't bore you by covering that. The IEEE standard originally defined two variants, the 32-bit single-precision format and the 64-bit double-precision format.</p>
<p>But that's not all you can do. If you understand the principles behind it, you can <a href="https://en.wikipedia.org/wiki/Minifloat">make your own floating-point format at any precision</a>. The most popular small-float format is the <a href="https://en.wikipedia.org/wiki/Half-precision_floating-point_format">16-bit half-precision format</a>. Popularized by Nvidia and ILM, this is supported in hardware by most GPUs.</p>
<p>The half-float format is great because it's good enough for many cases, while only being half the space of the standard 32-bit format. It's not just the space either -- the PS3 GPU, for example, would often run twice as fast when using halfs. (Interestingly enough, this usually wasn't due to the precision difference, but to restrictions on register file access. The smaller data access allowed the compiler to better schedule the instructions.)</p>
<p>There's a downside to this flexibility though. With regular FP, you can usually just throw it in there and not have to worry about precision. That's no longer true for half-floats. Every time you use them you now have to worry about whether it's suitable for the current case. And, as you may discover here, the results can be surprising.</p>
<p>The format is very simple; it's basically the same as the 32-bit version but with less bits:</p>
<table>
<thead>
<tr>
<th>Sign</th>
<th>Exponent</th>
<th>Mantissa</th>
</tr>
</thead>
<tbody>
<tr>
<td>1 bit</td>
<td>5 bits</td>
<td>10 bits</td>
</tr>
</tbody>
</table>
<p>The <a href="https://en.wikipedia.org/wiki/Half-precision_floating-point_format">Wikipedia page</a> has a good detailed explanation of it, but the trouble with just running the numbers on it is that you don't really get a good <em>feel</em> for understanding it. We need a better way of grasping the fundamentals.</p>
<p>To get a good visualization of half-float, the most useful property we can use is the fact that they're only 16-bit. This means that there's only 65536 of them. You know, that's not actually that many. So, why not just list them all out? I did just that. That's the great thing about computers today, data doesn't seem as big as it used to be. Once you have all the data in front of you at once, it's much easier to get a grip on it.</p>
<div class="admonition download">
<p class="admonition-title">Download</p>
<p><a href="wrangling-halfs/halfs.zip">halfs.zip</a> (406KB) - A list of every single half-float.</p>
</div>
<p>This text file has come in very useful for me on several occasions, and I'd recommend keeping a copy of it around for any time you're doing graphics work. Let's see what we can discover from this. We'll start by making a simple table, showing off the ranges at which the precision changes:</p>
<table>
<thead>
<tr>
<th>Exponent</th>
<th>Starts at</th>
<th>Step between each number</th>
</tr>
</thead>
<tbody>
<tr>
<td>0</td>
<td>0</td>
<td>1/16777216</td>
</tr>
<tr>
<td>1</td>
<td>1/16384</td>
<td>1/16777216</td>
</tr>
<tr>
<td>2</td>
<td>1/8192</td>
<td>1/8388608</td>
</tr>
<tr>
<td>3</td>
<td>1/4096</td>
<td>1/4194304</td>
</tr>
<tr>
<td>4</td>
<td>1/2048</td>
<td>1/2097152</td>
</tr>
<tr>
<td>5</td>
<td>1/1024</td>
<td>1/1048576</td>
</tr>
<tr>
<td>6</td>
<td>1/512</td>
<td>1/524288</td>
</tr>
<tr>
<td>7</td>
<td>1/256</td>
<td>1/262144</td>
</tr>
<tr>
<td>8</td>
<td>1/128</td>
<td>1/131072</td>
</tr>
<tr>
<td>9</td>
<td>1/64</td>
<td>1/65536</td>
</tr>
<tr>
<td>10</td>
<td>1/32</td>
<td>1/32768</td>
</tr>
<tr>
<td>11</td>
<td>1/16</td>
<td>1/16384</td>
</tr>
<tr>
<td>12</td>
<td>1/8</td>
<td>1/8192</td>
</tr>
<tr>
<td>13</td>
<td>1/4</td>
<td>1/4096</td>
</tr>
<tr>
<td>14</td>
<td>1/2</td>
<td>1/2048</td>
</tr>
<tr>
<td>15</td>
<td>1</td>
<td>1/1024</td>
</tr>
<tr>
<td>16</td>
<td>2</td>
<td>1/512</td>
</tr>
<tr>
<td>17</td>
<td>4</td>
<td>1/256</td>
</tr>
<tr>
<td>18</td>
<td>8</td>
<td>1/128</td>
</tr>
<tr>
<td>19</td>
<td>16</td>
<td>1/64</td>
</tr>
<tr>
<td>20</td>
<td>32</td>
<td>1/32</td>
</tr>
<tr>
<td>21</td>
<td>64</td>
<td>1/16</td>
</tr>
<tr>
<td>22</td>
<td>128</td>
<td>1/8</td>
</tr>
<tr>
<td>23</td>
<td>256</td>
<td>1/4</td>
</tr>
<tr>
<td>24</td>
<td>512</td>
<td>1/2</td>
</tr>
<tr>
<td>25</td>
<td>1024</td>
<td>1</td>
</tr>
<tr>
<td>26</td>
<td>2048</td>
<td>2</td>
</tr>
<tr>
<td>27</td>
<td>4096</td>
<td>4</td>
</tr>
<tr>
<td>28</td>
<td>8192</td>
<td>8</td>
</tr>
<tr>
<td>29</td>
<td>16384</td>
<td>16</td>
</tr>
<tr>
<td>30</td>
<td>32768</td>
<td>32</td>
</tr>
<tr>
<td>31</td>
<td>infinity/nans</td>
<td></td>
</tr>
</tbody>
</table>
<p>There's quite a few surprises nestled away in here. Perhaps the most shocking is the extreme precision loss at the high end. After 32768.0, you're stepping over 32 integers at a time! Even as low as 1024.0, you're still stepping 1.0 each time. Just to ram that point home, <em>numbers higher than 1024 lose <strong>all</strong> fractional precision</em>.</p>
<p>The maximum half-float possible is only 65504. That's not very big for many applications. And even at that range, you're only accurate to +/- 32.</p>
<p>Thinking of storing UV co-ordinates at half precision? Think again. At the 1.0 range our halfs are only accurate to 1/1024. For a 4096x4096 texture that means they're only accurate to every 4 pixels.</p>
<p>Trying to store a displacement map at half-precision? If it's in the 0-1 range, you're effectively only getting the same accuracy as a 10-bit format. That might be OK for a simple effect, but don't try it for a heightfield.</p>
<p>To summarize, while half-floats are great and you should use them whenever possible, you have to check your range first. How much precision do you require? It's easy to assume that a floating-point format will just magically give you everything you need, but it's not always so. Once you get outside the 0-1 range, half-floats lose their appeal for many cases.</p>]]></content:encoded>
	</item>
	<item>
		<title>The Metaprogrammer</title>
		<link>http://www.codersnotes.com/notes/the-metaprogrammer</link>
		<pubDate>
			Tue, 06 Sep 2016 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/the-metaprogrammer</guid>
		<content:encoded><![CDATA[<p><a href="the-metaprogrammer/laptops.jpg#right#thumb"><img alt="A sea of MacBooks" src="the-metaprogrammer/laptops.thumb.jpg#right#thumb"></a></p>
<p>There are some topics which, if posted onto a forum or news site, cause programmers to spew out more blather than all the rest put together. Such topics include:</p>
<ul>
<li>What kind of office chair you should have.</li>
<li>The benefits of a closeable office door over an open-plan office.</li>
<li>The brand of keyboard you use to type with.</li>
<li>The configuration or quantity of your monitor(s).</li>
<li>Standing desks.</li>
<li>How long it takes you to resume work after an interruption.</li>
</ul>
<p>You post an article about a new programming language, you'll get 10 replies. But start a discussion on what headphones you wear while you work, and ten-thousand people will rise up from nowhere, pushing the thread ever-skywards on a tower of upvotes. These things are not programming, but you can bet your bottom dollar that they'll get the most programmer attention every time they come up. Therefore we can suppose that this must be <em>metaprogramming</em>. You might have thought that metaprogramming meant macros, type introspection, that kind of thing. Nope, I'm hijacking the word for today:</p>
<dl>
<dt>metaprogramming</dt>
<dd><em>(verb.)</em> The act of talking about programming, rather than doing any actual programming.</dd>
</dl>
<p>Perhaps like the screenwriter who can only write if they are <em>seen</em> to be writing whilst in Starbucks, the metaprogrammer is concerned more with the appearance of work than the work itself. It's a kind of Schrödinger's Programmer - only by observing the programmer can we collapse the wave function. If the programmer is not <em>seen</em>, does he really even exist? Does an unwatched programmer begin to fade away like the Cheshire Cat, until all that remains is the fedora?</p>
<p>A coder I know (whom I won't name) once said that he would <em>only</em> ever consider someone to be a good programmer if they had a twitch livestream about programming. As if a programmer who isn't visibly metaprogramming on live TV can't even be considered to be competent. They sure have some exciting ideas for streaming entertainment nowadays: "Come see the wonderous optimizing! Watch live as he waits for Visual Studio to load!"</p>
<p>The metaprogrammer needs to be pampered. If they don't have the shiniest Apple MacBook then they can't work. Never mind that their job involves typing letters into a text file, something you could have done on CP/M back in '78. Gotta have that 40" monitor, it's essential, can't work without it. To insult a new hire by providing only a single 4:3 monitor? I can't work like this. This keyboard doesn't even have any OLED keycaps on it. This is an outrage.</p>
<p>Maybe it's just an insecurity, and they need these things to feel better about the work. Much like a comfort blanket perhaps, or a little desk toy they keep on their workstation. Can't program without it, it helps me think. There's another one -- "workstation". No, I couldn't possibly use something as pedestrian as a "computer", I need a <em>workstation</em> dammit. With chrome plating and fuel injection.</p>
<p>If you want to run a startup today, you gotta have a cafe. That's the perk people want above all else. Ask people why they want to work at Google, they won't talk of their desires to work on world-changing projects, or the opportunity to apply cutting-edge tech. No, they'll say "because of the free food!". The perks, my friend. The perks are everything. No-one cares about what you do there, but whether you get a free massage, or bagels supplied every morning like manna from heaven.</p>
<p>I've seen people almost come to blows over who gets the Aeron chair. I've seen artists who demand the luxurious corner office, with the luxurious view, and then put paper over the windows to stop the light coming in. I've seen companies buy MacBook laptops for every employee, even though they're never taken away from the desks.</p>
<p>Some of the best programmers I've ever worked with <em>don't have twitter accounts</em>. It's almost unthinkable, isn't it? How can they possibly be one of the top programmers in the world, building the most successful projects out there, without being <em>seen</em> to be doing it? You can write beautiful code, the best code in the world, but it doesn't mean a damn today if you didn't blog about your new standing desk.</p>
<p>When did the messenger become more important than the message?</p>]]></content:encoded>
	</item>
	<item>
		<title>The Multi-Project Programmer</title>
		<link>http://www.codersnotes.com/notes/multi-project-programmer</link>
		<pubDate>
			Fri, 26 Aug 2016 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/multi-project-programmer</guid>
		<content:encoded><![CDATA[<p>Every now and again I see this odd little pattern pop up. You'll be using some software, some big-name famous thing perhaps, and you'll happen across an article on-line where you discover it was written by <em>just one guy</em>. That's not <em>so</em> unexpected perhaps; every project probably started as one man's idea. The odd part is when you delve a little deeper into the history of this guy, only to find out he <em>also</em> wrote this other piece of software you use.</p>
<p>I see it happen time and time again. Look at <a href="https://en.wikipedia.org/wiki/Ludvig_Strigeus">Ludvig Strigeus</a>. Maybe you'll have heard of him as the guy who wrote <a href="http://wiki.scummvm.org/index.php/ScummVM_History">ScummVM</a> along with Vincent Hamm back in 2001. But did you also know he then went on to make <a href="https://www.openttd.org">OpenTTD</a> (a clone of Transport Tycoon) a couple of years later? That would have been enough for some people, but no, he still had a pressing need inside him to write a program called <a href="http://www.oldversion.com/windows/utorrent-2-2-1-2">uTorrent</a>. To finish off he went away and started work on a little music thingy called <a href="https://www.spotify.com/">Spotify</a>.</p>
<p>Or <a href="http://bellard.org/">Fabrice Bellard</a> for example. The man's a menace, he should be locked up. He's managed to litter a trail of big-name projects behind him -- <a href="http://ffmpeg.org/">FFMPEG</a>, which powers probably half of the video players in the world. <a href="http://wiki.qemu.org/Main_Page">QEMU</a>, one of the most famous machine emulators out there. Or <a href="http://bellard.org/tcc/">tcc</a>, the tiny C compiler which can boot Linux <em>from the source code</em> in 15 seconds. Oh and he wrote an entire <a href="http://bellard.org/jslinux/">Javascript PC/Linux emulator</a> which runs in a browser. We need to stop him before he creates SkyNet or something.</p>
<p>There's <a href="http://www.stevestreeting.com/2014/10/23/self-sourcetree-exit/">Steve Streeting</a>, the creator of the <a href="http://www.gamasutra.com/view/news/105533/QA_Steve_Streeting_On_Open_Source_3D_Engine_OGRE_3D.php">Ogre3D scene-graph library</a>, but also the creator of <a href="https://www.sourcetreeapp.com/">SourceTree</a> (the hg/git client). Or <a href="http://www.1014.org/code/">Justin Frankel</a>, not just the main author of <a href="http://arstechnica.com/business/2012/06/winamp-how-greatest-mp3-player-undid-itself/">Winamp</a> but also the <a href="http://www.salon.com/2000/03/15/gnutella/">Gnutella file-sharing program</a>, who then also went on to help create the <a href="http://www.reaper.fm/">REAPER audio workstation</a>. Many older readers might remember <a href="http://dallashodgson.info/articles/dpaint.htm">Dan Silva</a>, the guy who wrote <a href="http://www.computerhistory.org/atchm/electronic-arts-deluxepaint-early-source-code/">Deluxe Paint</a>. But did you also know he then went on to put together some seriously big parts of <a href="http://cgpress.org/archives/cgarticles/the_history_of_3d_studio">Autodesk's 3D Studio</a>?</p>
<p>I happened to be browsing the list of <a href="https://en.wikipedia.org/wiki/Hugo_Award_for_Best_Short_Story">Hugo sci-fi award nominees</a> when one name stuck out at me - the 1975 'best short story' nomination for a guy called P.J. Plauger. Wait, <a href="http://www.dinkumware.com/">that P.J. Plauger</a>? Yep, turns out that when he's not writing C++ runtime libraries he spends his time winning the John W. Campbell Award for Best New Writer.</p>
<p>I'm not even going to mention Elon Musk.</p>
<p>You should take some of this with a pinch of salt. I don't want to imply these guys did <em>all</em> the work on their projects -- FFMPEG has <em>loads</em> of contributors. ScummVM is the work of many people. But each of them started from a little seed, a seed which was planted by one person.</p>
<p>So what is it that these guys have that apparently no-one else does? Maybe they're just geniuses, but I don't think that's it. I think maybe they just a have a good eye for quality. They have strong ideas about the kind of things they want to exist and they're not afraid to get on with it.</p>
<p>There's a saying which I'm too lazy to look up but goes something like "don't invest in companies, invest in people." Software is one of the few areas where one guy on his own can have an idea and see it through from start to finish. The days of the lone inventor in his garden shed are long gone, but the spirit remains; it's just changed mediums.</p>
<p>I don't really know what I'm getting at with all this. I just find it interesting that there are people out there who aren't limited to one thing. There's supposed to be 7 billion people in the world, yet I find the same names cropping up again and again when you least expect them to. Maybe there are only 500 real people in the world and all the rest are NPCs, who knows.</p>
<p>I suspect what I'm experiencing is <a href="http://www.stevemcconnell.com/ieeesoftware/eic10.htm">cargo cult development</a> - that there's some underlying process I'm not understanding, and I'm just the guy studying the symptoms with the hope of figuring out the cause. Perhaps I'll never know. Still, there are people out there managing a string of unexpected hits, with no signs of stopping. Best of luck to 'em, I say.</p>]]></content:encoded>
	</item>
	<item>
		<title>The Elegance of Deflate</title>
		<link>http://www.codersnotes.com/notes/elegance-of-deflate</link>
		<pubDate>
			Sun, 21 Aug 2016 07:00:00 -0000
		</pubDate>
		<category>notes</category>

		<guid isPermaLink="true">http://www.codersnotes.com/notes/elegance-of-deflate</guid>
		<content:encoded><![CDATA[<p>A little while back I found need of a PNG loader for a <a href="https://bitbucket.org/rmitton/tigr">small project of mine</a>. Being a complete tool I of course decided to write my own -- after all, why save yourself effort when there are still wheels waiting to be reinvented? You can check the <a href="https://bitbucket.org/rmitton/tigr/src/be3832bee7fb2f274fe5823e38f8ec7fa94e0ce9/src/tigr_inflate.c">source to the inflater code here</a> if you so like - it's quite cleanly written. In fact I wrote it specifically to be easy to read, rather than to be the fastest implementation.</p>
<p>I didn't know much about Deflate at the time. I knew it was based on the LZ family of algorithms (LZ77/L7SS etc). I'd heard anecdotally that it was "just" LZSS except they applied Huffman coding on the match vectors. Well, it turns out that's kinda true. Kinda. But as I read deeper into the specification, it stuck me that something really quite clever was going on here, something I hadn't seen anyone explicitly call out before. So I figured why not try and explain the essence of Deflate here. I'm not going to cover the whole workings in exacting detail; if you want that go read the spec.</p>
<p>Deflate was invented by Phil Katz back in 1993, and forms the basis of the ZIP file format, the zlib library, gzip, PNGs, and probably a whole bunch of other stuff. At the time it was pretty cutting-edge. The main competition back then was usually LZW, or maybe LZSS. In many people's eyes compression was still synonymous with run-length encoding, so when Deflate came along it definitely turned some heads. Now this was over 20 years ago, and so later codecs like LZMA (which I may one day write about) can regularly beat it by a healthy margin. Still, it ain't dead yet.</p>
<div class="admonition errata">
<p class="admonition-title">Errata</p>
<p>So the basic principle described here was also used by the LHA archiver, which predates PKZIP 2.0 by a little. Perhaps I should arguably be titling this article "The Elegance of LHA"? Well I'm not going to, so there. History is written by the victors, and the guys with the better acronyms.</p>
</div>
<h3 id="compression">Compression</h3>
<p>There's two basic approaches to compression. OK no, that's not true, but let's go with it anyway and press onwards. To be honest if you know anything about compression already you may well be glossing over much of this, but here it is regardless.</p>
<ul>
<li>Entropy based compression</li>
<li>Dictionary based compression</li>
</ul>
<p>Entropy based compression is a very old idea. Computers usually store letters as 8-bit; one byte for each letter. "What a waste," someone thought. Some letters like <strong>E</strong> and <strong>T</strong> are very common, while letters like <strong>Q</strong> and <strong>Z</strong> rarely come up at all. It makes sense that you'd want to use less bits for the letters that are more common.</p>
<p>
<div class="caption right"><a href="elegance-of-deflate/freqs.png#right#thumb"><img alt="" src="elegance-of-deflate/freqs.thumb.png#right#thumb" title="Frequency counts of the Declaration Of Independence. Lower-case dominates, with capitals almost absent."></a><p>Frequency counts of the Declaration Of Independence. Lower-case dominates, with capitals almost absent.</p>
</div>
</p>
<p>This idea even predates computers. Go look at Morse code -- the two most common letters in English (E and T) are just a single dot and dash.</p>
<p>Huffman coding is a very old and simple way to apply this. You start with an "alphabet" - the set of all the symbols you want to encode. In English at school we're taught that our alphabet is 26 letters. In computers however we need a little more. We need to store upper-case letters, lower-case letters, numbers, punctuation, we need a symbol for a 'space', and a few other little things. Once you have your full alphabet you need to assign probabilities. We know some letters (e/t/a/i/etc) are more common than others (q/x/y/z/etc), but we also have to take the rest of this expanded alphabet into account. Numbers are rare in English prose, and so are capitals. This paragraph has five-hundred and sixty-one lower-case letters in, but only ten capitals.</p>
<p>Once you have your probabilities all sorted out, you build a Huffman tree. This assigns a unique code to each letter, except in a way that's "self-terminating". i.e. you don't need to store any additional information to say where each letter starts and stops. If you look at the example of Morse code, it doesn't work like that. While Morse has dots and dashes, it also has gaps, and the gaps are needed to split the letters up. Huffman coding needs no gaps.</p>
<p>So that's entropy encoding -- you decide upon an alphabet, you use less bits to store the common things and more bits for the rare things. You can compress things like English language with it, and while it works fine it leaves a lot of room for improvement. The are better ways than Huffman coding of course, like arithmetic coding, but Huffman's the easiest to get your head around. It's also what Deflate uses, so we'll leave it there.</p>
<h3 id="lz77">LZ77</h3>
<p>LZ77 forms the basis of the dictionary-based algorithms. The idea of dictionary compression is simply that certain things come up more than once in a document. For instance, if you search this page for the word "compression" it'll appear several times. So rather than store it again each time, let's try and refer to the previous usage.</p>
<p>LZ77 worked very simply. You store the match vector (a pair consisting of length and distance), and following the match you store the letter (the "literal") which ended the match.</p>
<p>So for example, if I want to store the phrase <code>sense and sensibility</code>, we see that the <code>sens</code> part is used twice. So we might store the second usage as <code>go back 10, copy 4, letter i</code>, because we need to copy the 4 letters of "sens" and then stick a new <strong>i</strong> on the end.</p>
<p>Seems fine, right? Nope, LZ77 sucked. Although it could save space by referring to previous phrases, that was <em>all</em> it could do. The pattern was fixed - it stored a match, followed by a letter. But what if there was no match? To use the same example, here's how LZ77 would <em>actually</em> store that whole quote:</p>
<blockquote>
<p><strong>Input:</strong> sense and sensibility<br>
<strong>Output:</strong> [back 0, copy 0]<strong>s</strong>[back 0, copy 0]<strong>e</strong>[back 0, copy 0]<strong>n</strong>[back 0, copy 0]<strong>s</strong>[back 0, copy 0]<strong>e</strong>[back 0, copy 0] [back 0, copy 0]<strong>a</strong>[back 0, copy 0]<strong>n</strong>[back 0, copy 0]<strong>d</strong> ...  </p>
</blockquote>
<p>What a mess. You get the idea though. It <em>has</em> to store a match, even if there isn't one. And storing that empty match information takes space. A typical vector might be 16 bits (12 bits for the distance back, 4 bits for the length). So something that was previously 8 bits per letter could now end up as 24 bits per letter! This is why no-one uses raw LZ77.</p>
<p>So they invented LZSS, which is what many of the early archivers used. LZSS stores a single bit to say whether the next thing coming up is a match vector, or a literal symbol. It's such a painfully obvious idea I'm at a loss as to why it wasn't thought of sooner. So now our extra marker bit allows us to flag whether a match vector is empty, and simply skip all that wasted overhead.</p>
<p>Anyway, that's dictionary compression. It works very well, when it's able to get lots of good matches going. It's that extra bit, though. That pesky "literal" bit we use to indicate whether we got a match. What happens if there aren't any matches? In that case, we've gone from originally storing 8 bits per letter to storing 9 bits! If no matches occur, LZSS will store 1 bit to indicate a literal letter, then 8 more bits to store that letter!</p>
<p>LZ77, LZSS and others in the family all suffer from the same problem, the overhead of having to switch modes -- when they find something that doesn't fit into the class of dictionary-based matches, they need to write out some kind of marker to switch over to the literal mode. This all takes up valuable space in the stream. (if you're not careful, sometimes you'll waste so much overhead doing this kind of switching that you won't actually compress the file at all, you'll enlarge it!)</p>
<p>So we have two compression algorithms. LZSS is reliant on finding previous data to match against, and Huffman coding is reliant on some letters being more common than others. Can we do better than picking one of those two? Can we weave them together?</p>
<p>Yes we can.</p>
<h3 id="deflate">Deflate</h3>
<p>If we want to munge these two algorithms together, it's not a great leap to imagine how we might do it. We start from LZSS right? The matching part seems OK, it's just the literals that are bogging us down as they're completely uncompressed. So how about this -- we could just Huffman encode them? We store a bit to say if it's a match or a literal, and if it's a match then we write a 16-bit match vector, and if it's a literal then we write a variable-length Huffman-encoded symbol.</p>
<p>That'd work just fine I suppose, but it's not how Deflate does it. Deflate goes further than that. You're still paying the cost of that marker bit to switch modes. In order to understand Deflate we need to expand our idea of what an alphabet is.</p>
<p>You see, when we hear the word "alphabet" we think back to what we learned as children -- A,B,C, etc. But the moment we start getting involved in compression we <em>know</em> that isn't the case. We have already had to expand our alphabet to include upper-case, and numbers and such. Even spaces, which aren't even visible, we have to encode those too. Deflate just takes this concept one step further.</p>
<p>Deflate is based around the idea of the <em>unified alphabet</em>. If an alphabet is just a set of choices, why not bring <em>all</em> the choices together under one umbrella? Deflate's alphabet consists of 286 symbols. The first 256 are the ASCII codes for each letter, including all the ASCII control codes and other such. The remaining 30 symbols are used to represent <em>lengths</em>. That's right, we're storing the actual match length here. Here's the actual table used:</p>
<table>
<thead>
<tr>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>0-255</td>
<td>Regular input byte</td>
</tr>
<tr>
<td>256</td>
<td>End of data block</td>
</tr>
<tr>
<td>257</td>
<td>Match of length 3 (distance follows after)</td>
</tr>
<tr>
<td>258</td>
<td>Match of length 4 (distance follows after)</td>
</tr>
<tr>
<td>259</td>
<td>Match of length 5 (distance follows after)</td>
</tr>
<tr>
<td>260</td>
<td>Match of length 6 (distance follows after)</td>
</tr>
<tr>
<td>261</td>
<td>Match of length 7 (distance follows after)</td>
</tr>
<tr>
<td>262</td>
<td>Match of length 8 (distance follows after)</td>
</tr>
<tr>
<td>263</td>
<td>Match of length 9 (distance follows after)</td>
</tr>
<tr>
<td>...</td>
<td>etc</td>
</tr>
</tbody>
</table>
<p>There's a bit more to it than just that, which I've omitted here for clarity, but hopefully this should explain the principle. We have 286 symbols now, and each one will be assigned its own probability, and therefore its own Huffman code. We know that some letters are still going to be more common (E, T, etc). But what about the matches? How common are they?</p>
<p>Remember how we had the frequency diagram of English text earlier? Well here's how it looks with our expanded alphabet:</p>
<p>
<div class="caption"><img alt="" src="elegance-of-deflate/alphabet.png" title="Frequency counts of the Declaration Of Independence, when Deflate compressed."><p>Frequency counts of the Declaration Of Independence, when Deflate compressed.</p>
</div>
</p>
<p>You can see that the lower-case 'e' is popular, as are some of the other lower-case ones like 'a/i/t/etc'. Capitals are almost non-existent, and there are no number digits at all in this case. Yet something sticks out like a sore thumb -- the dictionary matches which dominate the probability domain. It's also interesting that the probabilities of the lower-case letters have changed, due to the dictionary matches evening it out.</p>
<p>As we compress the data one symbol at a time, we face a choice at each stage of compression. If we can find a previous match then we can just write that match vector out, and if we don't then we write the literal symbol. But the special beauty of Deflate that sets it apart from its predecessors, is that whatever option we pick, we're only ever writing out a single Huffman-coded symbol.</p>
<p>If we want to store two matches in a row, or two literals in a row, we can do that. One alphabet to store two different ideas. No bit markers needed to designate a switch between modes. We're storing literal letters compressed according to their frequency, we're also storing match lengths according to <em>their</em> frequency, but more than that we're doing both of those things under one unified scheme.</p>
<p>It's not one algorithm but two, that dance and weave together in harmony. You can pick dictionary matching, or entropy coding, and you can select between them on a <em>per-byte basis with no overhead</em>. That's what I find so clever about it - not that it can do one thing or the other, but that it can choose either, and yet represent them using the <em>same language</em>. No extra markers, nothing to say "oh, now we're switching to entropy mode", nothing to get in the way.</p>
<p>It's an RLE encoder, it's a dictionary matcher, it's a frequency table, and it's all of these things with no barriers in-between, no modes to switch nor separate passes to run.</p>
<p>Deflate remains an excellent example of how two algorithms can come together and play off one another, rather than fighting against themselves.</p>
<p>I gotta admit, I'm impressed.</p>]]></content:encoded>
	</item>

	</channel>
</rss>
