When I first started coding, especially when I first did C++, there was a lot of confusion about where exactly the ‘game’ was, and more specifically, what a main game loop looks like. Because these days, all you hip kids code in Unity or Gamemaker or MyFirstIDE or some other colorful beginners IDE for the under 5s*, you never actually see your game loop, and have no idea where it is, let alone what it does., However, us real-men who code from the ground up have to write one. Here is mine from the PC version of Democracy 3. There are few comments, because in my godlike knowledge, I understand it all at a glance.

======================================================================================
void APP_Game::GameProc()
{
    HRESULT result = GetD3DEngine()->GetDevice()->TestCooperativeLevel();
    if(FAILED(result))
    {
        if (result == D3DERR_DEVICELOST )
        {
            Sleep( 50 );
            return;
        }
        else if(result == D3DERR_DEVICENOTRESET)
        {
            if (!GetD3DEngine()->Restore())
            {
                // Device is lost still
                Sleep( 50 );
                return;

            }
            Restore3D();
        }
        else
        {
            Sleep( 50 );
            return;
        }
    }

    GTimer looptimer;
    looptimer.StartTimer();
#ifndef _GOG_
    GetSteam()->Process();
#endif //_GOG_
    GetInput()->Process();
    GUI_GetCursor()->SetCursorStyle(GUI_Cursor::DEFAULT); //reset each frame...
    if(BActive)
    {

        GUI_GetMusic()->Process();
        GUI_GetSounds()->Process();
        if(PCurrentMode)
        {
            PCurrentMode->ProcessInput();
        }
        SIM_GetThreadManager()->ProcessFrame();
        GetTextureHistory()->Reset();
        LOCKRENDERTHREAD;

        GetD3DEngine()->BeginRender();
        if(PCurrentMode)
        {
            PCurrentMode->Draw();
        }
    
        GUI_GetTransition()->Draw();


        GetD3DEngine()->EndRender();

        RenderFont();
#ifdef _DEBUG
        if(GetInput()->KeyDown(VK_LSHIFT))
        {
            GetTextureHistory()->Draw();
        }
#endif //_DEBUG
        GetD3DEngine()->Flip();    

        RELEASERENDERTHREAD;

        looptimer.Update();
        if(looptimer.GetElapsed() < 16.0f)
        {
            looptimer.Update();
            if(looptimer.GetElapsed() < 16.0f)
            {
                Sleep(0);
            }
        }
    }
    else
    {
        ReleaseResources();
    }

    if(BRestartPending)
    {
        BRestartPending = false;
        SilentRestart();
    }
}

======================================================================================

*yeah I’m mocking different IDEs. deal with it :D This is sarcasm. There is no proven link between masculinity and choice of game development environment.**

**yet.

6 Responses to “Sample C++ game loop : Democracy 3”

  1. CdrJameson says:

    if(FAILED(result))
    {
    if(result == D3DERR_DEVICENOTRESET)
    {
    if (!GetD3DEngine()->Restore())
    {
    // Device is lost still
    Sleep( 50 );
    return;
    }
    Restore3D();
    }
    else
    {
    Sleep( 50 );
    return;
    }
    }

    Would do, wouldn’t it?

  2. Vinicius says:

    I respect that you code from the ground up and everything. But i think it is ridiculous to do that (in the context of you game), because of the time wasted creating stuff that you wouldn’t need with an “game engine for babies” and an infinity of problems concerning portability and all.

    I would like to be proven wrong with a nice answer!

    • CdrJameson says:

      There are two general approaches to not having to write everything yourself.

      1) Framework/game engine. This takes control of everything and provides a main loop which you never see. You write your own custom bits that get called by the framework when it says it’s your turn to do something. Typically methods like step() or startDraw() or similar, which you implement and the engine calls. You have no control over when this happens, and you can only chip in when the engine lets you.
      Gamemaker, Blitztech, Unity use this system

      2) Libraries. You are the ultimate master of destiny and write your own game loop, but some of the functions you call are provided by other people. In this case they might provide a draw() method, but you decide when to call it. You have more control, but you also have to write a (largely identical) game loop for each game. Examples of this approach are DirectX, SDL, STL, OpenAL etc.

      The advantage of the first is that it’s very easy to get something working quickly, however you have to dance to the framework’s tune and hope it does what you want.

      The advantage of the second is you have more control and flexibility.
      This also lets you mix and match libraries and have as many as you like (one for graphics, one for sound, another for UI, physics etc. etc.).
      Try combining multiple Frameworks and see how far you get.

      Anyway, I should butt out and see if my compilation has finished. Sorry for all the chatter…

  3. Les says:

    Guys, this engine has been developed a way before any of those shiny frameworks have been available. It’s also probably carrying over some code from his first game.

    My code looks the same and it still sells well :-D
    So what’s the matter if there is spaghetti code below?

  4. Cantrem says:

    Bah, a main loop snippet without the actual loop… this makes me sad, you have to include the “while(1)” !!