Day 1. Setting Up the Windows Build

Day 1. Setting Up the Windows Build
Video Length: 1h13

Welcome to Handmade Hero! This is a series where we program an entire game, from scratch, explaining each and every little piece that goes into creating games along the way.

Over the years, a whole community has spawned around the project. Head over to Handmade Network if you have any question or comment!

Additionally, if you preorder Handmade Hero, you will receive access to the GitHub repository, containing complete source code (tagged day-by-day) as well as community ports to other platforms. If you get stuck somewhere during this course, be sure to check it out!

Keep in mind that everything we're going to show you in this course is only one way of programming a game. In this course, we will present you how Casey makes games, so that you can see one complete way of doing it. You are encouraged however to develop your own styles and techniques, and experiment with trying different things and see what works the best for you.

No prior knowledge of programming is required to start following along. The only thing that will help you along the way is the basic knowledge of Windows, the insides of a computer on a basic level (what's a CPU, Graphics card, Memory, Motherboard). Knowledge about that binary number system, that a byte is 8 bits and that a kilobyte is 1024 bytes, as well as the basics of color theory (RGB) would definitely help as well.

Day 2

(Top)
Start the Project
  1.1  Set Up the Compiler
  1.2  Command Line in Windows
  1.3  Set Up the Text Editor
    1.3.1  4coder Setup
    1.3.2  VSCode Setup
Create the First Code File
  2.1  Minimum Code You Will Need
Configure Everything for Development
  3.1  Set Up Environment Variables
  3.2  Build.bat
Debugging in RemedyBG or Visual Studio
  4.1  Set Up RemedyBG
  4.2  Set Up Visual Studio Debugger
  4.3  Debugging Your Program
  4.4  Call Stack
Add Something to Do for the Program
  5.1  Import a Library
Recap
Exercises
  7.1  A Different Message Box
  7.2  Respawning Message Boxes
Basics of Programming
  8.1  Entry Point on Windows
  8.2  Bitwise Operators
Side Considerations
  9.1  Create a Virtual Drive
10  Navigation

   

Start the Project

The first thing we're going to do is to get a simple project started. We do it by setting up all our tools and by building something to ensure that our tools are working properly. While it may be a bit of drudgework, it's a vital step to ensure that, when moving forward, the project can be continued successfully without any interruptions.

To program our game, for the starters we will only need the following tools:

These tools, as well as few more advanced tools will be the focus of this Day.

   

Set Up the Compiler

A compiler is something that takes the source code that you type, and it translates it into what's called “an object file”.

The role of the linker then is then to gather all of the (usually) independently compiled object files and compose (link) them together it into an executable file.

Compiling and linking are two different stages of producing executable file from the source code. We will learn about compilers and linkers in the following sections and chapters.

For a more in-depth overview of how compiler and linker work, you can watch the short series Intro to C where these topics are covered in detail.

This course assumes you follow along on a machine with x86 (preferably one with 64-bit support) processor running Windows 7, 8 or Windows 10.

We will use the Microsoft Visual C++ compiler, or MSVC. MSVC is part of Visual Studio IDE (Integrated Development Environment). You can download the free Community Edition at visualstudio.microsoft.com and follow the installation instructions:

  1. Run vs_community.exe file that will be downloaded after the prompt.
  2. Accept the terms and conditions.
  3. Wait for the installer setup to complete.
  4. In the Workloads section, select only Desktop development with C++
  5. You can further reduce total space required by leaving only the following tools (### stands for current version number of the tools):
    • MSVC v### - VS 2019 C++ x64/x86 build tools
    • C++/CLI support for v###
    • Windows 10 SDK (highest version available)
    • IntelliCode (If you are planning on using Visual Studio as your text editor)
  6. After that, the development tools will be installed

If you don't intend to use Visual Studio debugger (in case you're able to use other debugger, like GDB, WinDBG or Remedy), you can save yourself some bandwidth and disk space by only downloading and installing Build Tools for Visual Studio. Note that some of the paths will be different in such case.

Although in practice this does not reduce space by too much. In total that still weighs a few gigabytes.

Once you are done, you can quickly test if everything was installed correctly by searching for “Visual Studio 2019" in your Start menu. You will be greeted with the Visual Studio IDE:

 Figure 1: Visual Studio Development Environment

This tool may be used to write, compile and debug the code. Feel free to use Visual Studio editor tools to develop your code, though this course will use a different route and show how to use the compiler, text editor and debugger separately.

Other than that, depending on your choice of debugger (see Subsection 4), you might only access this IDE for debugging purposes.

We will compile our code using Command Line Interface (CLI) for MSVC.

   

Command Line in Windows

In 2020 world, the command line is getting somewhat of a comeback on Windows. Still, while on Linux the command line is omnipresent, it's still possible that you have used Windows without ever accessing it.

To open a command line, simply search in your Windows Start Menu for Command Prompt. Alternatively you can hit Win+R and type cmd, or hit Win+X and then type C key.

When you open it, you will be presented with a simple text window:

 Figure 2: Default Command Prompt Window

This text window allows you to have dialogue with your computer the old-fashioned way: with the text commands. For instance, typing dir command lists the contents of the current directory (shown as the path in the prompt), del [filename] deletes the specified file (be careful, it won't be put into the trash bin!), cd [path] changes the current directory to the one specified by path.

If you're completely unfamiliar with the command lines, check out a handy command list on Wikipedia.

You might want to customize your Command Prompt font, colors, layout, etc. To do that, you would need to have Command Prompt shortcut saved somewhere, preferably on desktop. Close your Console window and create a shortcut to the Command Prompt. Open the Console through that shortcut.

Copying shortcuts from Windows 10 Start Menu

Please note that, if you are using your default Windows 10 theme, you cannot Click and Drag the shortcut to copy it. Instead:

  1. Search for Command Prompt in the Start Menu
  2. Right-click on the shortcut → Open File Location
  3. In the Explorer window that opens, find the link to Command Prompt and copy it to desktop.

If you now right-click and select Properties window, you will be able to customize a world of settings. For instance, you can specify the starting location for your terminal. By default, it starts in your user folder, which isn't very helpful if you keep your codebase somewhere else.

To set up your starting location:

  1. Pick up a place where you will keep your codebase (for example, D:\Documents\Codebase).
  2. Open Command Prompt PropertiesShortcut tab.
  3. Specify the Start in location to be your codebase location.
  4. Navigate the other tabs to set up the color, font and layout options of your preference.
  5. After restarting your Command Prompt, it will start with the color scheme and in the location specified.

For your convenience, these are the preferences we're using:

 Figure 3: Command Prompt window properties

As the first action in your new terminal, let's create a directory for our project!

As a refresher, Command Prompt works by processing commands. Any line you type into it is considered either a command, or a name of a file (either a program or a script). Each command is executed from a directory which is represented before the > symbol. The first word is the command, and then usually follow parameters that this command may or may not recognize.

For instance, if we type cd .. we send a command “Change Directory” with parameter .. (Two dots mean “Parent directory”).

If we type dir, we send the command “Show contents of the directory” with no parameters, the command will print the contents of a directory. The first parameter is the path of the directory to view contents of.

Again, if you're completely unfamiliar with the command lines, check out a handy command list on Wikipedia.

If your codebase is located on a different drive than the one you start in, you'll need to “switch” the drives first. This means typing the drive's letter followed by the colon (like D: if you want to switch to drive D). Below we assume that your codebase is located at the D:\Documents\Codebase.

C:\Users\Yakvi> D: D:> cd d:\documents\codebase D:\Documents\Codebase> mkdir handmade D:\Documents\Codebase\> cd handmade D:\Documents\Codebase\> _
[Command Prompt] Creating your work folder

An extra thing that we'd like to touch regarding the Command Prompt is discussed in the Create a Virtual Drive subsection.

   

Set Up the Text Editor

To edit the source files, any text editor can do the job. Notepad on Windows, for example, is perfectly capable to do it. However, text editors created specifically for the purposes of source file editing come with a variety of additional features, such as automated formatting, code highlighting, smart completion, quick navigation, etc.

We will occasionally provide relevant tips on how to use the editor 4coder. In this section, we will provide some setup tips both for 4coder and Visual Studio Code (also know as VSCode), an alternative text editor developed by Microsoft.

One thing to note that, as a rule of the thumb, when selecting your editor you should carefully choose how much it gets in your way, and compare it versus the various quality of life improvements it offers. Perhaps, there's a way to replicate the improvements or at least mitigate the distractions?

   

4coder Setup

4coder is a minimalist, cross platform, programmable, code editing environment, catering to the needs of low level programmers. It is available for free on itch.io.

After you downloaded 4coder, you will get a zipped folder. Unzip it somewhere, for example to w:\apps. Now, you can open it by double-clicking 4ed.exe, and it will open with 4coder as its working directory.

 Figure 4: Main window of 4coder

As the top message on the screenshot says, if you hit Alt-X shortcut and type in “demo”, you can select command hms_demo_tutorial. Follow this tutorial to get a hang of its main features.

Overall, Alt-X is the main command lister. For instance, if you would like to change the theme from theme-4coder to theme-handmade-hero, hit Alt-X, type in theme and choose the appropriate theme from the Theme lister.

If you'd like to change your default settings, open the config.4coder file (using the Interactive Open command or by hitting Ctrl-O shortcut), and default_theme_name to the theme of your choice. While you are here, check out other settings like mode or automatically_load_project. Hit Ctrl-S to save your changes.

You can further customize your 4coder experience by writing extensions directly in C++! For additional information, check out the 4coder wiki.

If you want to start 4coder from your code directory, type the following command in the Command Line:

W:\handmade\code> w:\apps\4coder\4ed
[Command Prompt] Starting 4coder from Command Prompt

You can also add 4coder shortcut script, we'll look into it in Set Up Environment Variables subsection.

   

VSCode Setup

Visual Studio Code is a free editor by Microsoft. One of its main advantages is a high availability of user-made and official extensions, however because it's using Chromium it might become rather memory-intensive.

You can download VSCode and get started with it here. If you choose this editor as the editor of your choice, here are some recommended extensions you might want to add to your environment (listed in alphabetical order).

Keep in mind many of these are of personal preference!

Overall, however, you might want ot disable anything else that would distract you from development: Minimap, Menu bar, Side bar and the terminal (when you aren't using them).

 Figure 5: Visual Studio Code

You can also enable autosaving by clicking File → AutoSave. Default is autosave after 1 second of inactivity, but you can change autosave options in the preferences.

If you're using IntelliSense, you might want to consider to tinker with you C/C++ Configurations:

  1. Press F1 and type the option “C/C++ Configurations” (you can choose UI or JSON)
  2. As Include path (includePath in JSON) set your code folder: ${workspaceFolder}/code/**

We're peeking a bit in the future, but you might want to also force include your platform .cpp file by adding its full path to the forcedInclude list.

Writing code directly in Visual Studio

If you would like to use Visual Studio as your editor, you can follow the guide outlined here: Setting up project in Visual Studio

   

Create the First Code File

Once we have our compiler and text editor at the ready, we can launch the latter and make a simple single C++ source file that we use to actually get our build going.

  1. Launch your text editor.
  2. We need a folder where all our code would live. Create a folder called code inside your handmade directory. You can use the following command line prompt:

W:\handmade> mkdir code W:\handmade> cd code D:\Documents\Codebase\> _
[Command Prompt] Creating code folder

  1. Create a new text file and save it as win32_handmade.cpp inside your code folder.

In 4coder, you can create both the directory and the file in one go, by hitting Ctrl-N and typing their names.

   

Minimum Code You Will Need

In this file we're going to do absolutely nothing (yet). We're going to insert just the entry point for Windows. Where to learn more about this? Whenever you're programming on Windows, you might want to always check out a website called MSDN (now also known as Microsoft Docs). It is the documentation of everything that is on Windows.

Learn ins and outs of MSDN!

Much of the Windows core functionality has fallen into obscurity or obfuscated by the newer API. Additionally, while this newer API is actively pushed by Microsoft and many developers, this might not be something you actively need in game development. So searching for the minutia of the programming API on Windows might become complex. The MSDN is huge, and it's hard to find your way around. So one reason this course exists is exactly to help finding the correct (or some of the correct) calls and articles. Hopefully this series will become a backbone that would show you want to search for.

However, even if we will present the direct links to many of the articles, this doesn't mean that you should learn how to use MSDN. If you want to program on Windows, you'll need to learn to navigate this website, read these pages and understand what they say in order to fully understand everything that's going on.

If we search for WinMain, which is the entry point for Windows, you will quickly find the related article. WinMain is the entry point that Windows will be looking for in our program1, everything starts from here. Its syntax is specified at the top of its MSDN article we provided above:

int CALLBACK WinMain(
  HINSTANCE hInstance,
  HINSTANCE hPrevInstance,
  LPSTR     lpCmdLine,
  int       nShowCmd
);
[MSDN] WinMain function syntax, or signature.

This is the part we copy and paste in our win32_handmade.cpp file. We will also include the file windows.h, which is the header file on Windows containing many of the function definitions that we will need to call in order to get our job done.

#include <windows.h>

int CALLBACK 
WinMain (HINSTANCE hInstance,
         HINSTANCE hPrevInstance,
         LPSTR     lpCmdLine,
         int       nShowCmd)
{
}
 Listing 1: [win32_handmade.cpp] Our first code

We assume that the reader has a basic knowledge of reading C code. If not, you can watch the short series Intro to C to get you started. To recap, what happens is that we're including a header file, the definitions of functions we can call and types we can use that Windows wants us to use in order to communicate with us. And lower below is the entry point where Windows pass us some parameters:

We aren't going to do anything in here, other than returning 0. In WinMain, this stands for “everything ran smoothly, we're done here”.

int CALLBACK
WinMain (HINSTANCE hInstance,
         HINSTANCE hPrevInstance,
         LPSTR     lpCmdLine,
         int       nShowCmd)
{
return (0);
}
 Listing 2: [win32_handmade.cpp] C expects us to return something here, so we are returning 0.
   

Configure Everything for Development

We'll leave our source file as a stub, because we need to get this building and executing as it is. Before we can do that however, we need to do some final preparations.

   

Set Up Environment Variables

To compile, we're going to call Visual Studio, that we installed earlier (see Set Up the Compiler subsection), or rather its command cl. Unfortunately, even after you've installed Visual Studio you will get an error:

W:\handmade> cl
'cl' is not recognized as an internal or external command, operable program or batch file.
[Command Prompt] Trying to call cl

The reason for it is that every command is being looked up in the system Path. If we type cl we can't find it because it's not in the Path. The basic way of doing it would be running a particular script that will set up our command line for us.

The file we're looking for is called vcvars64.bat. It's located deep inside the Visual Studio install folder. In Windows Explorer, head over to your Program Files (x86), find the folder Microsoft Visual Studio, and then go down until you find folders VCAuxiliaryBuild.

For Visual Studio 2019 Community edition, this path would therefore be C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat.

You can easily find a reference to it if you search for x64 Native Tools Command Prompt for VS 2019 in your Start Menu. Right click the link in the menu → Open File LocationRight click on the file → Properties, and copy the address in quotes in the “Target” window.

 Figure 6: Path to VCVars64.bat

Trivia: History of “Program Files (x86)"

The reason Visual Studio is in Program Files (x86) folder (instead of simply Program Files) is a historical accident. When Windows was running only in 32-bit on x86 processors, there was a push from Intel to go to a new processor line called Itanium, based on a proprietary 64-bit architecture. Meanwhile, due to the licensing limitation AMD stayed with x86. They started developing their own version of x64 architecture though, to stay competitive.

At the end, the Itanium project didn't pan out at all, even if it was championed by Intel. Nobody wanted to go to a completely new architecture and switch to this whole new thing so that didn't work out. It was AMD's architecture, a version of x86 upgraded to handle 64 bit (while being able to run the x86 code just fine) that was endorsed and adopted.

Also it was at that time that the 64-bit versions of Windows started to get published. We'll talk a bit more about the differences between 32-bit and 64-bit CPUs later in this course when it becomes more relevant. What happened also at that time however, probably due to an attempt to keep the legacy programs running, was Microsoft's decision to make two separate Program Files directories: programs that are compiled to run under the 32-bit version of Windows end up installed in Program Files (x86) one, while the programs compiled under the 64-bit version go into Program Files.

As for Visual Studio, as of 2020 it still hasn't been updated to run on 64-bit computers.

So now, if you run the vcvars64.bat in your Command Prompt you will see the following message:

W:\handmade>"C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Auxiliary\Build\vcvars64.bat"
********************************************************************** ** Visual Studio 2019 Developer Command Prompt v##.#.## ** Copyright (c) 2019 Microsoft Corporation ********************************************************************** [vcvarsall.bat] Environment initialized for: 'x64'
W:\handmade> _
[Command Prompt] Initializing Developer Environment for 64-bit version of Windows

If a path contains spaces, you need to enclose it in double quotes (")!

Note the vcvarsall.bat message. What vcvars64 does is simply calling vcvarsall and asking it to set up dev environment in 64-bit mode.

You can call vcvarsall.bat directly by replacing "PATH_TO_VISUAL_STUDIO\vcvars64.bat" with "PATH_TO_VISUAL_STUDIO\vcvarsall.bat" x64.

Note also that the “x64" part should go outside of the quotes.

So now, if you run cl in your Command Line, you will see a different message:

W:\handmade>cl
Microsoft (R) C/C++ Optimizing Compiler Version ##.#.##### for x64 Copyright (C) Microsoft Corporation. All rights reserved. usage: cl [ option... ] filename... [ /link linkoption... ]
W:\handmade> _
[Command Prompt] cl now works correctly.

Be mindful that this command must be run each time you restart your Command Prompt. In order to avoid doing it manually, you can set it up to run automatically:

  1. Create a new batch file named shell.bat, open it in any text editor. You can save the file in a directory called “misc” inside your project.
  2. Insert the following code:

@echo off

call "PATH_TO_VISUAL_STUDIO\vcvarsall.bat" x64
 Listing 3: [shell.bat] Setting up automated environment initialization.

  1. Save the file and exit.
  2. Open Properties to your shortcut to the Command Prompt.
  3. In the Target, add the line /k "[path to your shell.bat file]"

Upon restart of the Command Prompt, you should be greeted with the vcvars initialization messages.

You can go even one step further and expand your Path to include the misc directory, so that each time the system looks up a command it checks in there, as well.

@echo off

call "PATH_TO_VISUAL_STUDIO\vcvarsall.bat" x64
set path=w:\handmade\misc;%path%
 Listing 4: [shell.bat] Expanding your Path.

Quick 4coder launch

If you use 4coder, you can now add a shortcut 4ed.bat file inside your misc folder, containing the path to your editor:

@echo off

start [PATH_TO_4CODER]\4ed
 Listing 5: [4ed.bat] Shortcut to your editor.

The start command allows you to return to the Command Line without having to wait for 4coder to exit.

Now you can simply run the 4coder by typing in 4ed!

Last, you can add a command cls so that the screen is cleared after the environment has been set for us:

@echo off

call "PATH_TO_VISUAL_STUDIO/vcvarsall.bat" x64
set path=w:/handmade/misc;%path%
cls
 Listing 6: [shell.bat] Your final shell setup.

Remember to restart your terminal for the changes to apply!

   

Build.bat

If you got this far, congratulations! That is the drudgework of setting up a machine to actually develop on. We can now start our dev environment with a double-click on an icon, and we can run our editor, compiler and debugger from here. This is some great progress right there.

So anyway, if you can call cl from your command line, we can build an executable. That is mostly all we need. Let's get to compiling.

Here is how we are going to do the builds. It is highly unusual way3 in a world where the builds take complex make files.

In the root folder of our project (i.e. handmade), we will create a file named build.bat. A .bat (batch) file is a script, a list of things that the command line should do.

Trivia: The downsides of the Make systems

What other programmers do is setting up a so-called “Make system” using a tool like GNU Make, Ninja, CMake, etc4.

The reason why it's unusual is because people are used to the fact that compiling all the code takes a long time. The whole point of a make file is that you only compile that code that changed, and that's what these build utilities do: they try to optimize things so that they only do the minimal amount of work necessary to rebuild the project. And when projects tend to get very large, they tend to be very slow. But, as it turns out, if you just code sanely, you can compile very large programs (certainly larger than it would take to make a full professional game on this stream) in only a few seconds.

So, in our course, there're no build tools. There's only a batch file, that's all there is. And this batch file compiles the code. Compiles all the code, every time.

In conclusion, what we're going to do is to make the build.bat file:

@echo off

cl code\win32_handmade.cpp
 Listing 7: [build.bat] Your very own build file

We would take the source file we created in Subsection 2.1 and build it. This would be enough. However, we don't want to build it where it is right now, inside code directory. The compilation creates many secondary files which quickly mess up the code directory. Instead, we want the build output to go in a separate folder, let's call it build, to keep our source directory clean. For this, we will “virtually change” the folder using commands pushd and popd. Unlike the cd command, pushd remembers the original directory it switched from, so that popd can return to it once we're done.

We will also create a build directory if it doesn't exist already (using the command mkdir). The build directory will be living in handmade directory, so one step higher than the folder we're currently in (code), so we'll need to navigate “up” using the `..\` pseudo-directory.

@echo off
mkdir build pushd build
cl ..\code\win32_handmade.cpp popd
 Listing 8: [build.bat] Moving the output to the build directory.

So now, if you run the build.bat script and dir the build directory, you'll see your executable!

W:\handmade> build
Microsoft (R) C/C++ Optimizing Compiler Version XX.XX.XXXXX for x64 Copyright (C) Microsoft Corporation. All rights reserved. win32_handmade.cpp Microsoft (R) Incremental Linker Version XX.XX.XXXXX.0 Copyright (C) Microsoft Corporation. All rights reserved. /out:win32_handmade.exe win32_handmade.obj
W:\handmade>dir build
Directory of W:\handmade\build <dir> . <dir> .. 89,600 win32_handmade.exe 650 win32_handmade.obj 2 File(s) 90,250 bytes
W:\handmade> _
[Command Prompt] Building... Success!

Now you may ask: where does all the complicated build stuff come in? The answer is there isn't going to be any. The only additional thing is that we will start putting on the cl line additional things which are options to the compiler. Because the compiler has a lot of options, and we're going to specify how the compiler produces the executable. For instance, we can set already the -Zi flag (option) that, after rebuilding, would allow us to step into our code.

cl -Zi ..\code\win32_handmade.cpp
 Listing 9: [build.bat] Adding our first compiler flag.

MSDN lists the compiler flags with / instead of - (i.e. /Zi instead of -Zi). These are interchangeable on Windows, so use whichever you prefer.

Set up the project in 4coder

In 4coder, you can now setup your project so that each time you resume your coding session, you can pick up the code from where you left it. Simply hit the command setup_new_project and follow the instructions:

Alt-Xsetup_new_project

If you have automatically_load_project in the config.4coder set to true, the editor will automatically load your project on your next session.

To quickly build in 4coder, simply press Alt-M shortcut or F1 if you loaded your project. Alt-Comma closes the compile window.

   

Debugging in RemedyBG or Visual Studio

We now have a working Win32 program build by the Command Line using our own batch file. If we now want to step into that, we should start the debugger.

   

Set Up RemedyBG

We now need to set up the program through which we will be analyzing and debugging our code while it's running, i.e. a debugger. (Debugging is just a fancy word for “hunting for own mistakes”).

Visual Studio provides a debugger out of the box, and it's fine. Visual Studio itself is slow to boot and, overall is pretty gargantuan. For a nice sleek debugging experience, we recommend a debugger called RemedyBG. While still in development, this program already matches all of the essential functionality from Visual Studio.

RemedyBG is a paid debugger, but once you purchased it, it's yours to keep.

Once you downloaded the latest version, unzip it somewhere on your hard drive.

 Figure 7: RemedyBG debugger

Let's make a build.bat file in your misc directory to run it.

@echo off

start [PATH_TO_REMEDYBG]\RemedyBG build\win32_handmade.exe
 Listing 10: [debug.bat] Launching debugging in RemedyBG

You'll need to set where are we running the program from. In any relatively low-level piece of code there's a so-called “Current Working Directory”, from which the program was launched. Everything that you do when you reference external files in your code (like loading files) you should use with a relative path, relative specifically to Current Working Directory. In short, it's a path which is important for us to set from the get-go, so that we always reference things correctly.

In order to set ourselves for success, let's make a directory called data in the root handmade directory. In this directory, all the packaged assets (art, sounds, etc.) will live. Then, in RemedyBG, in the menu Session -> Working Directory, change it to W:\Handmade\Data.

 Figure 8: Setting your working directory in RemedyBG

Additionally, save your session so your settings are preserved, click Session -> Save as... and save it as misc/handmade.rdbg. You then can modify the debug.bat so that this session is loaded automatically.

@echo off
start [PATH_TO_REMEDY_BG_FOLDER]\RemedyBG misc\handmade.rdbg
 Listing 11: [debug.bat]
   

Set Up Visual Studio Debugger

If you aren't interested in trying out RemedyBG just yet, you can instead use debug.bat to start Visual Studio debugger:

@echo off

devenv build\win32_handmade.exe
 Listing 12: [debug.bat] Launching debugging in Visual Studio

If you run debug from your command prompt now, Visual studio will load a dummy solution. You can then right-click on the win32_handmade in Solution Explorer → Properties to change your Working Directory to w:\handmade\data. Click FileSave win32_handmade to save your solution as handmade.sln in misc folder, then modify your debug.bat file to load the solution directly.

If you don't see the Save As... dialog popping up, simply close the window. Visual Studio will ask you if you want to save your solution. Say yes, and save it.

@echo off
start devenv misc\handmade.sln
 Listing 13: [debug.bat]

 Figure 9: Setting your working directory in Visual Studio

As of writing, Visual Studio 2019 Community Edition doesn't allow editing of the working directory. If this still is the case at the time of reading this, you can still follow these steps and then open handmade.sln in your text editor. Change StartingDirectory value to W:\handmade\data and save the file.

This is one of the reasons why you should try out RemedyBG. ;)

   

Debugging Your Program

Since we specified our working directory to be Data, you should create this folder before we get going. Place it inside your handmade directory.

Once you completed your setup, while in the debugger, hit F11 on your keyboard or Control -> Step Into (Line) (RemedyBG) / Debug -> Step Into (Visual Studio). You will see your source file appear on the screen, and a yellow arrow indicating the start of your WinMain function body. This arrow represents your current position in the program execution. If you hit F11 a couple more times, it will go out of the program and into the disassembly (This is C runtime wrapping up your program exit). Hit Shift-F5 to stop the debug process.

 Figure 10: Debugging start!

   

Call Stack

The debugger can display a number of useful windows that you should know about:

And many, many more that might or might not be that useful. These are available in the Window menu of RemedyBG or in DebugWindow during a debug session on Visual Studio. We will touch on them at the various stages of this book. For now, let's look at the Call Stack.

Start a new debug session (hit F11 again) and open the Call Stack. You will see an entire “train” of functions that called each other until we arrived to the current point (if you don't see the full stack in Visual Studio, right click your call stack and select Show External Code).

Module name Function Name Address
win32_handmade.exe int WinMain(...) ...
win32_handmade.exe __scrt_common_main_seh() ...
kernel32.dll ...
ntdll.dll ...
 Table 1: Call Stack

The call stack is read from bottom up (most recent call at the top). ntdll.dll and kernel32.dll are the actual operating system. We are going to talk about what generally dlls are later, so let's skip those. But then the operating system calls into win32_handmade.exe, not into the WinMain we defined, but into __scrt_common_main_seh().

You can see the source of the CRT if you double-click the function on the call stack, in Visual Studio. RemedyBG doesn't provide the sources of the C Runtime Library.

In conclusion, if we really want to see where the code starts when Windows calls us, this is where the code starts. There's a list of things that happen first, that we did not write, to set up a bunch of things (which we really aren't going to use).

   

Add Something to Do for the Program

Let's have some fun. We worked so hard for this lesson, so let's just make something functional: a message box! This will also serve us as a test that our program is running properly.

In order to pop up a message box, we call the Windows function MessageBox. Let's open the link to see its syntax and copy paste in our program. Make sure to paste it inside the curly braces of your WinMain but before the return!

int MessageBox( HWND hWnd, LPCTSTR lpText, LPCTSTR lpCaption, UINT uType );
return (0);
 Listing 14: [win32_handmade.cpp] Adding a Message Box to our program.

int at the beginning is its return type. We don't care about this function's return value right now so we should remove it.

If you don't remove int before MessageBox, you will get the error C2440: 'initializing': cannot convert from 'initializer list' to 'int'!

Then, this function takes the following parameters:

Combining all these things together and putting them on one line, we get our Message Box call:

MessageBox(0, "This is Handmade Hero.", "Handmade Hero", MB_ICONINFORMATION | MB_OK );
return (0);
 Listing 15: [win32_handmade.cpp] Adding a Message Box to our program.

We can even go further and compress it on one line:

MessageBox(0, "This is Handmade Hero.", "Handmade Hero", MB_ICONINFORMATION | MB_OK);
return (0);
 Listing 16: [win32_handmade.cpp] Adding a Message Box to our program.
   

Import a Library

Now, if you try to compile now, the compilation will go fine, but you will be immediately halted by the linker which is called right after the complier:

/out:win32_handmade.exe 
/debug 
win32_handmade.obj 
win32_handmade.obj : error LNK2019: unresolved external symbol __imp_MessageBoxA referenced in function WinMain
win32_handmade.exe : fatal error LNK1120: 1 unresolved externals
[Command Prompt] Linker error

Let's look at the bottom two lines.

The compilation result is recapped by the fatal error LNK1120: there was 1 “unresolved external”, which is further clarified in the error LNK2019: we're missing one symbol __imp_messageBoxA. What does this mean?

During the compilation, the compiler (and the linker) only knows about the files that we specify in the cl line of our build.bat. In our previous compilation everything went smoothly:

In this case, the linker went to look for the function MessageBoxA declared in windows.h but not defined, and didn't find it.

However, there's something else that happens under the hood: we need to bind with (running) Windows at runtime, we can't just have its functions defined in our code. So the linker needs to find the places where we call Windows and patch those references with the Windows' own code that's running at that time in memory. In order to that, we need to use what's called an Import Library (not to be confused with the normal libraries, also .lib). This library will do just that: it will put some markers in our code that, upon its loading, will be found by Windows and pointed to the actual functions running in memory.

For a more in-depth overview of how dynamic linking works, you can watch the short series Intro to C where this topic is covered in detail.

We were able to link successfully beforehand, because there're a one implicit library that is imported together with the CRT (kernel32.lib). However if we try, for example, to call into the UI system to draw our message box, we need to let the linker know about a new library (user32.lib) to import.

To recap, when the linker combines all the .obj files and makes an executable, we should add an import library for the runtime functions that we use. Let's do just that:

cl -Zi ..\code\win32_handmade.cpp user32.lib
 Listing 17: [build.bat] Linking with user32.lib.

In MSDN, you can always look up the Import Library to be used at the bottom of the function article.

A and W suffixes in Windows functions

Note that the function linker was looking for is MessageBoxA, while we called for MessageBox. This is because in Windows, any function that takes a string as input has an ANSI and a Wide (Unicode) version, and a macro decides which function to call. By default, the ANSI mode is enabled, but you can short-circuit this and call the version you prefer directly:

MessageBoxA(0, "This is Handmade Hero.", "Handmade Hero", MB_ICONINFORMATION | MB_OK);
[win32_handmade.cpp]

   

Recap

And there you have it! Today, we covered a lot of ground: set up our tools for writing, building and debugging our program, our dev environment, compiled our first program, and even dived a bit into the intricacies of the compiler and linker! Tomorrow, we will start laying down the groundwork to open our window and display something on the screen.

 Figure 11: Our message box


 1 Technically, it's the entry point that the C runtime library (that links with our program) will be entering... We'll see about that in Subsection 8.1.

 2 If you right-click on any shortcut → Properties → Shortcut, you will see a run dropdown list with a few options like “Normal Window”, “Minimized”, “Maximized”. This is what's passed in nCmdShow. It's bizarre that Windows developers decided to pass it on together with the WinMain, and not through some function call.

 3 Or was, before Handmade Hero made its debut a few years back...

 4 People love their build tools. They have scripts that build their build files that their build tools modify for actual builds, with tools which are analysing their build tools... You get the idea. This however has a downside of having to mess around with your build tools a lot, just trying to get your stuff to build.

 5 This course will use 0 instead of NUL or nullptr. Feel free to use your preferred null identifier.

   

Exercises

Before we move on, make sure you are comfortable with all this. If you made mistakes and learned from them, it's even better! It's practice, trial and error which will solidify all these notions in you, so that by the end of the day you'll just know it.

Below we're proposing a few exercises but feel free to think about something different! This is your world, and you're the creator.

   

A Different Message Box

Instead of using MB_ICONINFORMATION | MB_OK flags, try to put a different set of flags to your MessageBoxA. Change a message. See what happens if you have more than one button and you click one.

   

Respawning Message Boxes

Use the return of MessageBoxA to potentially spawn more message boxes. Spam yourself.

   

Basics of Programming

In this section, we will be detailing some of important programming concepts that we will encounter along the way. Some of these will be general programming, some C-specific, and others might be even more specific than that.

   

Entry Point on Windows

WinMain is an entry point for windows applications. An entry point is a function that gets called, executes the code inside it, and returns to whoever called it.

But who called us in the first place? It's not actually the operating system that called us. "C Runtime Library” (CRT) was the one who's responsible for calling us. CRT is something that ships with all the C compilers, as mandated by the C specification (for Windows, you can find documentation on MSDN). In turn, the CRT was called by Windows.

It is possible to disable the CRT library to get called by the operating system directly. This can have positive effect on the size of your binary and the number of dependencies. However removing CRT is not simple, because compiler accounts on CRT for many things in our code. If you are interested to learn more, check out this discussion on Handmade Network.

   

Bitwise Operators

Bitwise operators are operators that have a specific action on single bits inside the value. Of these Bitwise OR operator (single vertical bar, |) is a bitwise operator which checks if each bit of two values is set. The resulting number will have all corresponding bits set.

In this case, bitwise OR is used in uType as a way of setting flags in a bit field, where each bit means a specific thing. by “ORing” the different bits together, you can have multiple things happening at once (in our case, we want the OK button to appear, as well as the information icon).

As you can see from the definitions in the Parameters section, MB_ICONINFORMATION is a label for “hexadecimal 40" (i.e. binary 0100 0000), while MB_OK is a label for 0. We still want to specify it to avoid confusion, should we decide to replace it with, for example, OK and Cancel button set (MB_OKCANCEL, 1).

This is a valid solution to a problem where the output is configurable. Depending on the situation, a similar solution might be achieved by:

(back to Section 5)

   

Side Considerations

In this section, we will be showcasing additional things you might want to do to make your life easier, and to follow more closely our own way of doing things.

   

Create a Virtual Drive

One command to note is subst. This command can be used to assign a drive letter (like Z:) to a path on a hard drive. This can come handy to point your codebase root folder, especially if you move the codebase to another machine or location.

For more details, simply type subst /? in the command line.

Trivia: subst and Amiga computer veterans

Casey notes that this habit of his is highly unusual, and that you can be completely free to skip it. It might be a legacy habit of him working a lot with the Amiga computers popular in the late 80's... or of the people who watched Handmade Hero a lot.

Let's assign w drive to our codebase, create a handmade directory in it, and move into the directory.

D:\Documents\Codebase> subst w: d:\documents\codebase D:\Documents\Codebase> w: W:\> cd handmade
[Command Prompt] Setting up your work folder

This command must be run again after you restart your PC. If you'd like subst to happen automatically when you boot your PC, create a startup.bat file with the following commands:

@echo off

subst w: [your codebase location]

Save this file in %appdata%\Microsoft\Windows\Start Menu\Programs\Startup folder.

So now, coming back to Command Prompt PropertiesShortcut, you can specify its Start in location as w:\handmade. Remember to restart!

 Figure 12: Customized Command Prompt Window next to the Properties Window

If you're coming from Subsection 1.2, you can continue by going to the Set Up the Text Editor subsection.

   

Navigation

Up Next: Day 2. Opening a Win32 Window

Back to Index

Glossary

References
MSDN Links

Import Libraries

MessageBox

WinMain

Compiler Options

-DEBUG Creates debugging information for the executable.

-Zi Generate a separate PDB file that contains all the symbolic debugging information for use with the debugger. Implicitly sets -DEBUG flag.

Other

Liberation Mono

Setting up project in Visual Studio

formatted by Markdeep 1.13