[video 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]