..
#gamedev

(Win) 001 - Setting Up Windows Build For Game Development in C

Configuring the environment to start programming is a boring but necessary step.

In this post, I will highlight how to set up a programming environment that works as simply as possible for game development on Windows.

Another post, I will share the process to set up the build for MacOS.

Command Line

The common steps for writing everything from scratch are to be comfortable with your tools, especially the command line.

You should configure the fonts, colors, and the window where you spend most of your time.

I like the bright brown colors. By the way, I created a theme with these colors that I use in Emacs and Jetbrains' IDE as well (that I use for mobile development). I call it the Terminator Theme.

Open up the prompt command (command line for Windows) with shortcut Win Key + R and type cmd.

Click on prompt command icon at top-left corner, access the properties menu and customize fonts and colors as you prefered.

1727034196.png

My configuration uses the color R=237 G=196 B=100 and Liberation Mono font.

Let's get back to the game-related stuff.

Virtual Drive (Optional)

The main goal of this post is to create a simple and focused environment where you can quickly code your game.

Following Casey Muratori I've learned the Virtual Drive approach.

The Virtual Drive simulates any position of physical drive, like c:\Users\yourname\somefolder or anything else.

To create a virtual drive uses the subst command. You can also see the options with subst /?.

subst w: c:\Users\yourname\somefolder

Now, use cd w: to go to your project folder. If everything works, you'll see a "w: driver".

Startup Virtual Drive

Windows uses a startup.bat file by default to run scripts.

Open the Dialog with Win + R and type shell:startup.

You'll see the the folder that contains the batch file.

Edit the file with notepad or any editor.

Write your subst command in startup.bat if you use virtual drives.

# startup.bat
@echo off
subst w: c:\Users\<username>\<your_project_folder>

Now, every time the system boots up, the virtual drive w: will appear.

Another approach is to use the standard c:\ as your HOME directory.

Compiler

To start writing a game we need a compiler. There are many compilers that compile C code into binary executables. In this project we'll use the MSVC on Windows and Clang on MacOSX.

You can download the Visual Studio and enable your command line to compile using only one script called vcvarsall.bat.

These script live inside the Visual Studio folder. I don't remember the exact path where it lives because Microsoft changes the path every release (sorry). Please find the script yourself.

In my case, the script location is C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\.

After running vcvarsall.bat x64 (for 64 bits compilation) in command line, you see the cl program enabled to compile our code.

vars.bat

But, find this script every time is boring. So, let's create another script to help us.

Create a script called vars.bat at c:\bin using the notepad. This script calls the vcvarsall batch file and add the c:\bin folder to the PATH. This way, you'll have a directory where you can add other batch files as you need like an emacs.bat for start up emacs or anything else.

REM vars.bat
@echo off
call "C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build\vcvarsall.bat" x64
set PATH=%PATH%;c:\bin

emacs.bat

Create a script emacs.bat inside c:\bin that is responsible by start up the emacs from command line.

REM emacs.bat
@echo off
call "C:\Program Files\Emacs\emacs-29.2\bin\runemacs.exe" 

After that, create a misc directory in the project to back up the emacs.bat and vars.bat files.

Remember, these files live on c:\bin and they can run from anywhere because the bin folder is included in the PATH.

Coding With Emacs

Emacs was created in 1976 by Richard Stallman and maybe you're thinking: "Oh man, this is an old editor!".

But it works for me!

I personally always used Vim since my first year as programmer, even during my internship, my boss required me to code and navigate quickly in any editor.

I met Emacs in HandmadeHero and I loved it.

I configured it a lot, spending many hours (nerd alert), and now it has become my favorite editor ever. I like to combine Emacs with Evil Mode to simulate Vim Key bindings inside Emacs.

Install Emacs on Windows and follow the next steps to work properly.

If you want to use the same version that I use, choose emacs-29.2_1-installer.exe 2024-02-01.

I put my .emacs file in c:\ and add computer environment variables HOME=c:\.

That way, the Emacs looks to the c:\ as location to the .emacs file.

You can find my version of .emacs file and .emacs.d folder in my dotfiles. It includes themes, snippets, scripts and more. Check it out.

But there's a catch ladies and gentlemen. These days, Windows does not allow Emacs to write files in c: unless the user is an Administrator. So, I like to disable any "required" write privileges on my own computer.

I disable UAC using Registry Editor that allow us to use c: as HOME and with full privileges.

Disable UAC Registry Editor (Optional)

Open up the Dialog box with Win + R and type regedit.

Navigate to the following registry subkey:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\policies\system
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Policies\system

In the right pane of the System key, find EnableLUA DWORD, then double-click on it.

Change the key value to 0, then click OK.

Reboot your PC to save changes.

Startup Command Prompt (Optional)

The command prompt can start up your vars.bat script when it opens.

Add the command prompt as shortcut on Desktop.

In the Properties > Target field, type after cmd.exe /k c:\bin\vars.bat.

Now when you open the command prompt the script will run and enable the compiler and path for all scripts inside the bin folder.

That means you can execute any custom command that is a batch file inside c:\bin. Super useful.

Writing First Program And Build

Create the src folder with win32_myproject.cpp and build.bat files.

build.bat

You only need the batch file to compile the program.

You can disregard tools like cmake, make and other build tools. Instead, write a simple batch file in c:\myproject\src\build.bat.

Inside the batch file I added a compiler flag for debugger -Zi, make dir build where executable lives and add a linker flag for compiling with user32.lib.

Also, I turn off output with @echo off at the top of the file.

REM build.bat
@echo off
echo "building..."

set LINKER_FLAGS="user32.lib"

IF NOT EXIST ..\build mkdir ..\build
pushd ..\build
cl -nologo -Zi ..\src\win32_myproject.cpp %LINKER_FLAGS%
popd
  • echo off: Disable the instructions output (print), in the other words, do not print the line. Now, the @ means to not print the first echo line as well.
  • pushd/popd: Navigate and persist at history as stack.
  • cl: Compile using MSVC compiler (Microsoft Visual C)
  • user32.lib: This is a static library that Windows create. The linker use it to find the correct implementation for components like MessageBox, Window and others.

While coding, you can compile directly using my Emacs configuration with shortcut M-x m or call the build.bat script from command prompt.

Main File

Create the entry-point at win32_myproject.cpp with WinMain and use the macro MessageBox from user32.lib to test the configuration where I set the icon warning and some buttons based on MSDN documentation to the message box.

// win32_myproject.cpp
#include <windows.h>

int APIENTRY
WinMain(HINSTANCE instance,
        HINSTANCE prev_instance,
        LPSTR cmd_line,
        int show_cmd)
{
    return MessageBox(NULL, "Hello World", "caption",
                      MB_YESNOCANCEL|MB_ICONWARNING);
}

The MessageBoxA forces the message to show as ANSI text.

Windows uses a Hungarian notation in its code. I don't particularly like it, but it's interesting to know because you'll use a lot the Windows code and MSDN documentation.

Windows also use a lot of macros to define a ANSI and Unicode utf-8 stuff, probably for compatibility reasons.

Run the Program

You can run the executable from command prompt like ..\build\win32_myproject.exe or using the Visual Studio for debugging.

Open the Visual Studio from command prompt with command devenv:

devenv c:\myproject\build\win32_myproject.exe

Because we compile our program with debug flags, the Visual Studio recognizes it.

Create a folder at root called data. This folder is useful when running the game from Visual Studio. I've set up at properties the data folder as working directory for Visual Studio.

With Visual Studio opened, right-click on solution > properites > Working Directory, and set the path to w:\your_project\data.

The F5 key runs the program in debug mode and F11 key stops at first line of the main function.

The first code that Windows runs is not our cpp file, is the crt0.c. They ship the source code with C Runtime Library (CRT) So, the TRUE startup is mainCRTStartup(). After at all, they dispatch to WinMain.

Conclusion

The article appears big, but it isn't in fact. When you follow step by step, you'll notice that is so simple and productivity and your workflow is much faster (double click at shortcut command prompt, type emacs, hit ENTER, write code, compile, debug with devenv, that's it).

The final structure is very simple.

myproject
├── data
├── misc
│   ├── emacs.bat
│   └── shell.bat
└── src
    ├── build.bat
    └── win32_myproject.cpp

The next step is to create a window and main game loop.

Review

Create misc directory to backup the emacs.bat and vars.bat file. This files lives on c:\bin.

The emacs.bat is responsible by start up the emacs.

The vars.bat file enables cl compiler using 64 bits compilation (x64). After, the c:\bin was added to PATH (if the user does not set it to environment variable).

Create the src folder with win32_vtmr.cpp and build.bat files.

Inside the batchfile I added a debugger flag -Zi, make dir build if needed and add a linker flag for compiling with user32.lib. Also, I'm turn off output with @echo off on top of file.

Create the entry-point at win32_vtmr.cpp with WinMain and use the macro MessageBox from user32.lib to test the configuration where I set the icon warning and some buttons based on MSDN documentation to the message box.

Create a folder at root called data. This folder is useful when running the game from Visual Studio. I've set up at properties the data folder as working directory for Visual Studio.

To run the game using debugger, run devenv c:\game\build\win32_game.exe.

My Quick Access

  • Install Visual Studio
  • Install Emacs and configure .emacs in c:\
  • Configure Windows Privileges and HOME c:\ environment variable
  • Configure the command prompt with fonts and colors
  • Set up subst virtual drive with startup.bat
  • Create the vars.bat file to enable cl compile and add c:\bin to the PATH
  • Configure the emacs.bat to start up from command prompt
  • Configure shortcut for command prompt
  • Write the main file with entry-point WinMain and a 'Hello World' by MessageBox
  • Write build.bat code to compile the program
  • Configure the data folder for Visual Studio working directory

References