[video member=cmuratori stream_platform=twitch stream_username=handmade_hero project=chat title="Drawing a Circle on a 286" vod_platform=youtube id=kVtDEy1ndYg annotator=Miblo]
[2:11][Upgrade ~remedybg to 0.2.4.2][:admin]
[3:12][@egnadh][Q: I remember you were asked what's the best way to draw a circle at a Microsoft job interview. What's the answer?]
[5:40][The "free" aspects of drawing a circle on a 286: the centre and cardinal radius points][:blackboard :geometry]
[8:10][Our target requirements: no floating point, wide instructions or threading; but branching is fine][:blackboard :geometry]
[11:10][Efficiently computing the circle's arc][:blackboard :geometry]
[26:13][Storing the error value, x and y][:blackboard :geometry]
[31:55][Plotting a mere eighth of the circle][:blackboard :geometry]
[37:11][Create bcircle.cpp (from "Bresenham Circle") and create a pixel grid to contain our circle][:blackboard :geometry :programming]
[40:10][Build and :run bcircle to see our pixel grid][:geometry :programming]
[40:49][Reduce the size of our pixel grid to 32×32 characters][:geometry :programming]
[41:04][Check out our smaller pixel grid][:geometry :run]
[41:19][Implement our error-based circle drawing routine][:geometry :programming]
[48:44][Check out our circle, to find that it is positioned incorrectly][:geometry :run]
[48:51][Fix our routine to plot the circle around its centre][:geometry :programming]
[48:57][Check out our circle, one eighth of it][:geometry :run]
[49:32][Make our routine plot our eighth of the circle around the entire circumference][:geometry :programming]
[50:05][Check out our fuller circle][:geometry :run]
[50:11][Prevent our routine from plotting the pixel grid's centre point][:geometry :programming]
[50:16][Check out our fuller circle][:geometry :run]
[50:24][Plot the initial pixel][:geometry :programming]
[50:32][Check out our perfect circle][:geometry :run]
[50:39][Optimise our routine, using one pointer initialised at the circle's centre in lieu of two stored Cx and Cy values][:geometry :optimisation :programming]
[54:31][Check out our same circle][:geometry :run]
[54:41][Consider how to remove the eight integer multiplies by the WIDTH][:geometry :optimisation]
[58:25][Temporarily make our routine test abs(E0) < abs(E1)][:geometry :mathematics :programming]
[58:46][Check out our identical circle][:geometry :run]
[58:55][Revert that -E0 < E1 test][:geometry :mathematics :programming]
[59:07][See that all remains identical][:geometry :run]
[59:10][Continue to consider how to remove the eight integer multiplies by the WIDTH][:geometry :optimisation]
[1:00:15][@Rounin][@cmuratori: X<<5?]
[1:00:20][Sully the WIDTH and HEIGHT so that they are not a power of two][:geometry :programming]
[1:00:51][@ggn2][@handmade_hero Calculate the initial X/Y into a pointer and increment that?][:geometry]
[1:01:26][@said6289][@handmade_hero Store XWidth and YWidth pointers that you increment accordingly every run][:geometry]
[1:02:12][Ruminate on our circle drawing routine][:geometry]
[1:02:50][@ggn2][@handmade_hero Well, I'm thinking on 68000 terms where there were a bit more registers than x86][:hardware]
[1:03:22][Consider the WIDTH multiply to have potential for improvement][:geometry :optimisation]
[1:04:00][Try to remove the Ep += 1 from the equation][:geometry :optimisation :programming]
[1:04:43][Check out our (different) circle][:geometry :run]
[1:04:50][Reinstate the Ep += 1][:geometry :optimisation :programming]
[1:06:29][@x13pixels][Q: Can you get rid of the "Ep += 1" line?][:geometry :optimisation]
[1:07:09][Try to negate X the whole way through][:geometry :optimisation :programming]
[1:08:17][Check out our same circle][:geometry :run]
[1:08:37][Assess our options, with X negated, and try plotting X and Y pixels from different eights of the circle][:geometry :optimisation :programming]
[1:13:31][Check out our barely-plotted circle][:geometry :run]
[1:13:35][Try looping while X <= (R / 2)][:geometry :optimisation :programming]
[1:14:02][Check out our big X][:geometry :run]
[1:14:06][Continue to try plotting X and Y pixels from different eights of the circle][:geometry :optimisation :programming]
[1:17:16][Plotting X and Y pixels from different eights of the circle][:blackboard :geometry :optimisation]
[1:18:41][Understanding why our X / Y plotting on different eighths doesn't work][:geometry :optimisation]
[1:20:55][@filiadelski][Q: I'm sorry we decided to go with another candidate because he went to Harvard]
[1:21:20][Midpoint[ref
    site=Wikipedia
    page="Midpoint circle algorithm"
    url=https://en.wikipedia.org/wiki/Midpoint_circle_algorithm] and Bresenham's circle drawing algorithm[ref
        site=GeeksforGeeks
        page="Bresenham’s circle drawing algorithm"
        url=https://www.geeksforgeeks.org/bresenhams-circle-drawing-algorithm/]][:geometry :research]
[1:23:22][Temporarily make our routine always increment the Y][:geometry :programming]
[1:23:48][Check out our circle with the Y always incrementing][:geometry :run]
[1:24:36][Revert our routine to not always increment the Y][:geometry :programming]
[1:24:39][Compare our circle][:geometry :run]
[1:24:41][Increase the radius of our circle][:geometry :programming]
[1:24:50][Check out our larger circle][:geometry :run]
[1:25:17][Leave further :optimisation as an exercise for the reader]
[1:26:40][Check out the register count of the Intel 386[ref
    site=Wikipedia
    page="Intel 80386"
    url=https://en.wikipedia.org/wiki/Intel_80386] and 286[ref
    site=Wikipedia
    page="Intel 80286"
    url=https://en.wikipedia.org/wiki/Intel_80286][ref
        site=WikiChip
        page="80286 - Microarchitectures - Intel"
        url=https://en.wikichip.org/wiki/intel/microarchitectures/80286][ref
    site=Wikipedia
    page="x86"
    url=https://en.wikipedia.org/wiki/X86] and suggest writing this routine in x86 assembly targeted at DOSBox's :emulation of a 286[ref
        site=DOSBox
        url=https://www.dosbox.com/]][:research]
[1:31:41][@alex_deak][Q: Hi Casey! (Sorry, it's pretty long, and has nothing to do with circles) I'm a mathematician, trying to be a graphics / engine programmer. I made some pet projects using OpenGL and Vulkan, in which I was able to make the things I wanted, but since my lack of enough experience, I had a hard time figuring out what "professional programming" is. I started watching [~hero Handmade Hero] in December from day 1, and I almost caught up (currently I'm at day 520). Thanks for this amazing series, it has been inc… \[sic\]]
[1:32:29][Wonder who is responsible for the message truncation]
[1:33:43][@alex_deak][Q: Do you have any advice about starting a career in graphics / engine programming for someone, who has a very strong background in mathematics, physics, can do research, perhaps can come up with creative ideas, wants to learn ab… \[sic\][ref
    site=YouTube
    page="HandmadeCon 2016 - Technical Direction at Blizzard"
    url=https://www.youtube.com/watch?v=jyA0csH4KNE][ref
        site=Milton
        url=https://www.miltonpaint.com/]]
[1:43:01][@ggn2][@handmade_hero For what it's worth, PCem[ref
    site=PCem
    url=https://pcem-emulator.co.uk] has cycle exact CPU cores if you want to be more accurate][:emulation]
[1:43:46][@tshugako][Q: On one of the first [~hero Handmade Hero] streams you said that it was faster to work (bitwise operations) on a uint32 than a uint8. Why?][:performance]
[1:50:08][@toideng][Q: Any opinion of Linux's way to define integer types with one letter (like u8, i16, i64)?][:language]
[1:51:21][@flightlesshippo][Q: Pug with a gun needs to be an enemy in the game]
[1:51:32][@printf_armin][Q: For a program for Windows only is DX the better or OpenGL?][:api]
[1:51:55][@saidwho12][@handmade_hero What do you think of getting a college degree in information technology? Should you instead be working on hobby projects? My dad has been wanting me to get into a post-secondary school for a long time]
[1:55:37][@centhusiast][Q: I have done lots of tools in C like a string utility, JSON parser, data visualization on Linux using X11, vector library and some other tools. Do you think these can be valuable for the CV?]
[1:59:32][@alex_deak][Q: Great, thank you! Do you think it's maybe enough to have a YouTube channel, instead of a webpage? Since I have no idea how to do a webpage... Or is it very basic knowledge that I should know?]
[2:00:31][Recommend The ryg blog[ref
    site="The ryg blog"
    url=https://fgiesen.wordpress.com/]][:research]
[2:01:55][@joeyiswatching][Q: Why were you suggesting to look at how to do it under 286? I just joined as you were talking about that]
[2:02:56][@boonetbe][Q: I've been using a :language with function polymorphism similar, I think, to what [@naysayer88 Jon] is doing in JAI, i.e. "multiple dispatch" / dispatch on input types. I recently tried out some different languages and found this is not at all very common. How come not more languages have this? Is it hard to implement, other issues?]
[2:04:40][@flightlesshippo][Q: I heard JAI is close to beta release? Will you be playing about with that or leaving it until it's matured more?][:language]
[2:05:10][@centhusiast][Q: Have you met the Amiga programmer like Bruce Dawson? It seems like they were the great programmers]
[2:06:33][@toideng][Q: Would you use sine / cosine now?][:mathematics]
[2:07:18][@victorn][Q: Are you going to push the circle solution to GitHub?]
[2:07:28][@unxx][Q: Do you ever use any scripting :language?]
[2:07:37][@toideng][Q: Is there any computer world outside US?]
[2:19:59][@centhusiast][Q: I saw some codes that use the array of function pointers and enums to avoid branching. enums like action type move_right, move_left and then function pointers associated with them. Do you think it is a good idea to do that?][:language]
[2:22:52][Understanding a Skylake core[ref
    site=WikiChip
    page="Skylake (client) - Microarchitectures - Intel"
    url=https://en.wikichip.org/wiki/intel/microarchitectures/skylake]][:hardware :performance :research]
[2:33:51][Branch-prediction in the context of a Skylake core[ref
    site=WikiChip
    page="Skylake (client) - Microarchitectures - Intel"
    url=https://en.wikichip.org/wiki/intel/microarchitectures/skylake]][:hardware :performance :research]
[2:38:48][Understanding the Skylake CALL instruction[ref
    site=Intel
    page="Intel® 64 and IA-32 Architectures Software Developer Manuals"
    url=https://software.intel.com/en-us/articles/intel-sdm]][:isa :research]
[2:45:23][@boonetbe][Q: I saw [@naysayer88 Jon] implement a compare and swap intrinsic recently for lock-free multithreading. Except for incrementing counters and stuff, what is it useful for? Do I understand it correctly that it's only useful when the thread-unsafe code / task is small?[ref
    author="Maurice Herlihy"
    title="Wait-Free Synchronization"
    publisher="Digital Equipment Corporation"
    url=https://cs.brown.edu/~mph/Herlihy91/p124-herlihy.pdf]][:threading]
[2:48:16][@boonetbe][Q: Why aren't we using analog computing, i.e. instead of bits use frequencies. Noise?][:hardware]
[2:49:17][@florian3321][Q: I am 50k lines into a C++ Android engine development (tried to stay away from inheritance and stuff. Note that I am still learning). Should I rewrite it the "C" way? How can I change my thinking? You at some point said that one should come to the point where OOP fails and then use non-OOP, but I think I am not really there yet. Hope this is not a dumb question][:language]
[2:50:24][@garryjohanson][Q: He did do a video on branch predictions, though I don't know if it's germane to what we're talking about[ref
    site=YouTube
    page="Rambling talk about CPU uArch stuff"
    url=https://www.youtube.com/watch?v=oDrorJar0kM]][:hardware]
[2:52:22][Recommend [@rygorous Fabian]'s entire YouTube channel[ref
    site=YouTube
    page="Fabian Giesen"
    url=https://www.youtube.com/channel/UCcRaa0AcYX32c0m8wJJHNWg/videos]][:research]
[2:53:01][Wind down]
[/video]
