At the end of day 29 we divide handmade.h into two header files, handmade.h & handmade_platform.h.
handmade_platform.h seems to be re-written to be compatible with pure C and contains most of the old handmade.h.
handmade.h now only has 3 structs: world, game_state and tile_map.
It also has two implemented functions safe truncate and GetController.
I didn't really understand why we did this. What is the architectural purpose of this division?
Also I thought header files were for declarations only, not implementation. Can someone explain what the real distinction is between having code in a .cpp and a .h file is, and why we have distributed our code in this way?
The pure C was done to facilitate porting handmade hero to non C++ platform (I think it was for the Swift port someone is doing).
The separation is to clearly separate what's the platform layer and what's the game layer so you can use the platform layer for another game directly.
The platform layer (the win32 code for example) only needs to include handmade_platform.h which is actually platform independent and the same on every platform (the name could be confusing). It contains informations needed for the communication between the platform and the game (the service).
handmade.h contains only things used by the game.
In day 29, win32_handmade.cpp still includes handmade.h but that has changed in a later stream.
There is no real distinction between .h file or .cpp. When you include a file (h, cpp, txt...) the precompile step copies the content of the included file into the includer file.
You generally put in .h file the "interface" of your code so someone in a different translation unit can include the .h and use your functions or classes without having to know about how they are implemented or where the code is. The linker will resolve where the corresponding code is. That's why you often only see inclusion of .h file in programs.
In handmade hero, Casey uses a unity bluid which means he want to minimize the number of translation units (~ the number of file you feed cl.exe). To do so he includes cpp files as well as h files in a "main" file (win32_handmade.cpp and handmade.cpp) so he only passes one big file to cl (there are 2 cl call in the build.bat so 2 translation units). Also note that the static keyword (internal, global_variable) limits the scope of a function or variable to the translation unit it is in.
I think inline functions need to be defined in the translation unit they are used in (inline means copy the function there instead of calling it; the compiler may choose not to do so). So you need to implement it in the header file so when someone includes the header, the translation unit contains the code the compiler needs to copy.