[video output=day529 member=cmuratori stream_platform=twitch stream_username=handmade_hero project=code title="Debugging the PNG Writer" vod_platform=youtube id=WFs7irxSpwc annotator=Miblo]
[0:01][Recap and set the stage for the day debugging our :font glyph PNG writer][:speech]
[4:59][Reacquaint ourselves with PNGFilterReconstruct()][:research]
[7:11][Try running test_png on the known-valid shot4_2.png][:admin :"asset system"]
[8:26][Craft a line that exports our :font glyphs and extracts liberation_mono_0089.png to .bmp[ref
    site="Ascii Table"
    url=https://www.asciitable.com/]]
[11:32][Invoke our test line to see that our .bmp output works, but for being upside-down][:admin :"asset system"]
[13:19][Reacquaint ourselves with the pre-multiplication of alpha in our PNG loader and .hha font extractor][:"asset system" :research]
[15:27][Prevent LoadGlyphBitmap() from pre-multiplying alpha, and instead produce a monochrome bitmap][:"asset system"]
[16:54][Run our exporter–extractor to see our monochrome .bmp][:admin :"asset system"]
[17:16][Make LoadGlyphBitmap() flip the bitmap's rows][:"asset system"]
[18:09][Run our exporter–extractor to see that our .bmp is off-by-one row][:admin :"asset system"]
[18:38][Fix LoadGlyphBitmap() to pad the image equally top and bottom][:"asset system"]
[19:13][Run our exporter–extractor to see our 1 pixel border][:admin :"asset system"]
[19:23][Determine to make our PNG writer comply with the PNG spec][:speech]
[20:40][Combine the PNG writer and reader, switching WritePNG() to write to a stream and introducing OutCopy(), OutStruct() and OutStructCopy()][:memory]
[27:22][Switch WritePNG() to use our new OutCopy() and OutStructCopy()][:"asset system"]
[33:06][Initialise a stream for WritePNG() to use][:"asset system" :memory]
[37:47][Delete our .png glyphs, run and crash png_test][:admin :"asset system"]
[40:20][~remedybg bug: Run-to-cursor switches focus from source to disassembly (if the latter was not open, opening it)][:admin]
[41:17][Step through WritePNG()][:"asset system" :run]
[45:18][~remedybg bug: Opening a recent session creates a breakpoint][:admin]
[46:00][Step through ParsePNG() in test_png to see that the Signature is wrong][:"asset system" :run]
[47:19][Investigate our incorrect Signature][:research]
[49:11][Run hhfont and fail to see the printout][:admin :"asset system" :font]
[49:42][Respecify DumpStreamToCRT() as DataStreamToFILE()][:"file io"]
[50:42][Run our exporter–extractor to see that we're producing the .bmp again][:admin :"asset system"]
[51:11][Run test_png on the known-valid shot4_2.png and compare its ZLIB header with one we produced for liberation_mono_0089.png][:admin :"asset system" :"file format"]
[52:00][Consult the ZLIB spec[ref
        site=IETF
        page="ZLIB Compressed Data Format Specification version 3.3"
        url=http://www.ietf.org/rfc/rfc1950.txt]][:"file format" :research]
[56:12][Make WritePNG() write out a valid FCHECK value[ref
        site=IETF
        page="ZLIB Compressed Data Format Specification version 3.3"
        url=http://www.ietf.org/rfc/rfc1950.txt]][:"file format"]
[1:00:15][Consult the PNG spec for the suggested CRC algorithm[ref
    site=W3C
    page="Portable Network Graphics (PNG) Specification (Second Edition)"
    url=https://w3.org/TR/2003/REC-PNG-20031110/]][:"file format" :research]
[1:02:53][Temporarily implement the ability to write out the CRC table][:hashing :"file io"]
[1:06:37][Generate our CRC table][:admin :hashing]
[1:06:45][Enable WritePNG() to write out our CRC[ref
    site=W3C
    page="Portable Network Graphics (PNG) Specification (Second Edition)"
    url=https://w3.org/TR/2003/REC-PNG-20031110/]][:"file format" :hashing]
[1:19:54][Run our exporter–extractor to see that we are producing .png files that Paint 3D can read][:admin :"asset system"]
[1:21:11][Consult the ZLIB spec for the ADLER32 algorithm[ref
        site=IETF
        page="ZLIB Compressed Data Format Specification version 3.3"
        url=http://www.ietf.org/rfc/rfc1950.txt]][:hashing :research]
[1:22:07][Enable WritePNG() to ADLER32 hash the data[ref
        site=IETF
        page="ZLIB Compressed Data Format Specification version 3.3"
        url=http://www.ietf.org/rfc/rfc1950.txt]][:hashing]
[1:28:38][Run our exporter–extractor, crash png_test and investigate why][:admin :"asset system"]
[1:31:26][Fix WritePNG() to include the checksum size in the ChunkHeader][:"asset system"]
[1:31:48][Run our exporter–extractor successfully][:admin :"asset system"]
[1:31:55][Hunt for a PNG validator and find pngcheck[ref
    site=pngcheck
    url=http://www.libpng.org/pub/png/apps/pngcheck.html][ref
        site=GitHub
        page="jbowler / pngcheck"
        url=https://github.com/jbowler/pngcheck]][:"file format" :research]
[1:35:46][Try pngcheck on liberation_mono_0089.png to see that we have a CRC error in chunk IHDR][:admin :"file format"]
[1:36:53][Carefully consult the PNG spec for the CRC information[ref
    site=W3C
    page="Portable Network Graphics (PNG) Specification (Second Edition)"
    url=https://w3.org/TR/2003/REC-PNG-20031110/]][:"file format" :hashing :research]
[1:39:30][Fix WritePNG() to exclude the length field from the CRC][:hashing]
[1:42:08][Run our exporter–extractor and crash test_png, but find that pngcheck and GIMP recognise our .png as valid][:admin :"asset system"]
[1:44:23][Run our exporter–extractor on the correct directories, and determine that we're in the clear][:admin :"asset system"]
[1:45:08][Q&A][:speech]
[1:46:35][@somebody_took_my_name][Q: I thought there should be an error because the type was endian swapped before the CRC was calculated, but apparently that is how it works]
[1:47:14][@pythno][Q: Hi [@cmuratori Casey], I think you would enjoy Revision demopary. There are plenty of people yelling "Amiga" frequently. And some of the Amiga demos and intros are very, very good[ref
    author="Revision Demoparty"
    title="Revision 2019 - Compo - Amiga Demo"
    publisher=YouTube
    url=https://www.youtube.com/watch?v=zwoyfH7TgEQ]]
[1:47:44][@xxthebigfoxx][Q: What do you think are other fields to look into to get hired as a systems programmer other than the game industry?]
[1:49:33][@somebody_took_my_name][Q: What does the align point for fonts stand for? The offset of a rectangle of size by size?]
[1:49:55][@bts1911][Q: Do you use any standard software development process while creating this game?]
[1:50:21][@teamrandb][Q: I missed it during stream, could you show what an .hht font file looks like?][:"file format"]
[1:52:21][@lucid_frost][Q: Are sampling profilers always strictly worse than adding counting points directly to the binary? I have trouble wrapping my head around the accuracy / quality of sampling][:profiling]
[1:55:43][@teamrandb][How do sampling profilers work? Do they need to pause every thread, or can they take a snapshot somehow and then figure out where the program was?[ref
    site=Intel
    page="Intel® 64 and IA-32 Architectures Software Developer Manuals"
    url=https://software.intel.com/en-us/articles/intel-sdm]][:profiling]
[2:07:56][@jkfsda][Q: How many game developers are there who actually care about :performance / :optimisation? Isn't most game development just simple things, e.g. made with Unity? Are these game devs that work in Unity as valuable as you said, that they can apply to web-scale companies and get an easy job with high salary?]
[2:09:25][@diffserv][300k at Google is no joke]
[2:09:46][Wrap it up][:speech]
[/video]
