CRM64Pro GDK v0.80.0
A free cross-platform game development kit built on top of SDL 3.0
Loading...
Searching...
No Matches
Tutorial 01: Basic application setup

Overview

This tutorial builds the smallest useful CRM64Pro graphical application. The program opens a 960x540 window, loads a background image and a ship image, moves the ship with the cursor keys and renders everything from the main loop.

It introduces the setup pattern used by later tutorials: initialize memory tracking, access Main and the core managers, configure logging, initialize timing, create the screen, process input through Main::update(), run fixed-rate logic and release resources cleanly.

Final result

CRM64Pro Tutorial 01 final result

Runtime controls

  • Cursor keys: Move the ship image.
  • S: Save Tutorial_01_Basic-Snapshot.png.
  • Any key or mouse click: Write the input event to the log.
  • Q or ESC: Exit the tutorial.

Prerequisites

What you will learn

  • Start CRM64Pro memory tracking with CMem.
  • Access Main and the core managers.
  • Configure Log, Timer and Screen.
  • Load PNG images with ImageMgr::loadFromFile().
  • Read SDL keyboard and mouse events through Main::update().
  • Update movement and render images at a fixed rate.

Step by step

1. Select the renderer and start memory tracking

The example first reads the renderer command-line option. It then enables CRM64Pro memory tracking before any engine resources are created.

eConfigRendererDriver eRenderer = CRD_SOFTWARE;
if(!runParameterReadRender(argc, argv, eRenderer)) return 1;
// Start CRM64Pro memory tracking before creating engine resources.
// atexit() releases memory tracking data when the program exits.
CMem::setStatsLevel(CMem::MSL_NORMAL);
atexit(CMem::destroy);

2. Access Main and configure logging

Main::instance() provides access to the engine managers. The default log writes to standard output and to the platform-specific tutorial output directory.

// Main gives access to the CRM64Pro managers.
Main& mC64 = Main::instance();
Log& mLog = *mC64.logMgr().get();
TutorialState state;
// Write log output to stdout and to a file under validation/bin.
mLog.init("Tutorial_01_Basic", LL_DEBUG, LM_FILE | LM_STDOUT, OUTPUTDIR"Tutorial_01_Basic.log");

3. Initialize timer and screen

The timer is initialized before the main loop. This first tutorial updates and renders at the same fixed rate of 20 frames per second. Later tutorials separate fixed-rate logic from rendering through a screen callback.

// Initialize the timer before calling Main::update().
// setRate() receives render frames per second, then logic frames per second.
mLog.msg(LL_INFO, " Initialize timer ... ");
if(!mC64.timer().init())
{
logTaskFailed(mLog);
Main::terminate();
return -1;
}
logTaskOk(mLog);
mLog.msg(LL_INFO, " Set frame rates (render=%d, logic=%d) ... ", iRenderRate, iLogicRate);
if(!mC64.timer().setRate(iRenderRate, iLogicRate))
{
logTaskFailed(mLog);
Main::terminate();
return -1;
}
logTaskOk(mLog);
// Add a 1 ms idle delay inside Main::update().
mC64.configMgr().setMTFriendly(1);
// Configure and show the default screen.
Screen* pScreen = mC64.configMgr().get();
pScreen->setSize(iScreenW, iScreenH);
pScreen->setDriver(eRenderer);
pScreen->setTitle("CRM64Pro - Tutorial 01: Basic");
mLog.msg(LL_INFO, " Create screen (%dx%d) ... ", iScreenW, iScreenH);
if(pScreen->show() < 0)
{
mLog.msg(LL_CRITICAL, "FAILED\n");
// Standard setup error path:
// 1. Log what failed.
// 2. Terminate the engine so initialized managers are cleaned up.
// 3. Return -1 to report application failure to the operating system.
Main::terminate();
return -1;
}
logTaskOk(mLog);

4. Load external images

The background and ship are loaded from PNG files. Every resource ID and object pointer is validated before the tutorial enters its main loop.

// Load external PNG images from validation/bin/Base.
// The second parameter is the resource name stored by ImageMgr.
mLog.msg(LL_INFO, " Load background image: %s ... ", RESOURCE_BG_IMAGE);
state.idBgImage = mC64.imageMgr().loadFromFile(RESOURCE_BG_IMAGE, "tutorialBasicBg");
if(state.idBgImage < 0)
{
logTaskFailed(mLog, state.idBgImage);
Main::terminate();
return -1;
}
logTaskOk(mLog);
mLog.msg(LL_INFO, " Load ship image: %s ... ", RESOURCE_PLAYER_IMAGE);
state.idPlayerImage = mC64.imageMgr().loadFromFile(RESOURCE_PLAYER_IMAGE, "tutorialBasicPlayer");
if(state.idPlayerImage < 0)
{
logTaskFailed(mLog, state.idPlayerImage);
Main::terminate();
return -1;
}
logTaskOk(mLog);
mLog.msg(LL_INFO, " Access background image object ... ");
Image* pBgImage = mC64.imageMgr().get(state.idBgImage);
if(pBgImage == nullptr)
{
logTaskFailed(mLog);
Main::terminate();
return -1;
}
logTaskOk(mLog);
mLog.msg(LL_INFO, " Access ship image object ... ");
Image* pPlayerImage = mC64.imageMgr().get(state.idPlayerImage);
if(pPlayerImage == nullptr)
{
logTaskFailed(mLog);
Main::terminate();
return -1;
}
logTaskOk(mLog);

5. Process input

The main loop repeatedly calls Main::update() while input and render processing continues; a return value of 0 signals the next fixed logic step. Quit events stop the loop, cursor keys update movement flags and S saves a screen snapshot.

while(mC64.update(&event))
{
if(event.type == SDL_EVENT_QUIT)
{
bRunning = false;
}
else if(event.type == SDL_EVENT_KEY_DOWN)
{
// SDL3 stores the key value in event.key.key.
mLog.msg(LL_INFO, " Key pressed: %s (%d)\n", SDL_GetKeyName(event.key.key), event.key.key);
if(event.key.key == SDLK_Q || event.key.key == SDLK_ESCAPE)
{
bRunning = false;
}
else if(event.key.key == SDLK_LEFT)
{
state.bMoveLeft = true;
}
else if(event.key.key == SDLK_RIGHT)
{
state.bMoveRight = true;
}
else if(event.key.key == SDLK_UP)
{
state.bMoveUp = true;
}
else if(event.key.key == SDLK_DOWN)
{
state.bMoveDown = true;
}
else if(event.key.key == SDLK_S)
{
mLog.msg(LL_INFO, " Save screen snapshot: %s ... ", OUTPUT_SNAPSHOT);
if(pScreen->saveSnapshot(OUTPUT_SNAPSHOT) == 0)
{
logTaskOk(mLog);
}
else
{
logTaskFailed(mLog);
}
}
}
else if(event.type == SDL_EVENT_KEY_UP)
{
if(event.key.key == SDLK_LEFT) state.bMoveLeft = false;
else if(event.key.key == SDLK_RIGHT) state.bMoveRight = false;
else if(event.key.key == SDLK_UP) state.bMoveUp = false;
else if(event.key.key == SDLK_DOWN) state.bMoveDown = false;
}
else if(event.type == SDL_EVENT_MOUSE_BUTTON_DOWN)
{
mLog.msg(LL_INFO, " Mouse clicked: button %d at %d, %d\n", event.button.button, (Sint32)event.button.x, (Sint32)event.button.y);
}
}

6. Update movement

updateLogic() converts movement flags into a per-step delta and clamps the ship position to the visible screen.

static void updateLogic(TutorialState& rState, Image* pPlayerImage, float fDeltaTime)
{
if(!pPlayerImage) return;
float fDX = 0.0f;
float fDY = 0.0f;
if(rState.bMoveLeft) fDX -= fMoveSpeed * fDeltaTime;
if(rState.bMoveRight) fDX += fMoveSpeed * fDeltaTime;
if(rState.bMoveUp) fDY -= fMoveSpeed * fDeltaTime;
if(rState.bMoveDown) fDY += fMoveSpeed * fDeltaTime;
const float fMaxX = static_cast<float>(iScreenW - pPlayerImage->getWidth());
const float fMaxY = static_cast<float>(iScreenH - pPlayerImage->getHeight());
rState.fPlayerX = clampFloat(rState.fPlayerX + fDX, 0.0f, fMaxX);
rState.fPlayerY = clampFloat(rState.fPlayerY + fDY, 0.0f, fMaxY);
}

7. Render the frame

The frame is drawn directly from main(): the background first, followed by the ship at its current position.

static void renderFrame(Image* pBgImage, Image* pPlayerImage, const TutorialState& rState)
{
if(pBgImage) pBgImage->render();
if(pPlayerImage)
{
SDL_FRect rDst = {
rState.fPlayerX,
rState.fPlayerY,
static_cast<float>(pPlayerImage->getWidth()),
static_cast<float>(pPlayerImage->getHeight())
};
pPlayerImage->render(0, nullptr, &rDst);
}
}

8. Complete the fixed step

After processing pending events, the loop exits immediately if a quit request was received. Otherwise, it performs one logic update and draws the new state.

if(!bRunning) break;
updateLogic(state, pPlayerImage, 1.0f / static_cast<float>(iLogicRate));
renderFrame(pBgImage, pPlayerImage, state);

9. Release resources

The tutorial closes one image by ID, closes the remaining ImageMgr resources and then terminates the engine.

mC64.imageMgr().info();
// Close one image by id, then close the remaining ImageMgr resources.
// close(0) closes all resources owned by that manager.
mLog.msg(LL_INFO, "\nCLEANUP\n");
mLog.msg(LL_INFO, " Close ship image by id ... ");
mC64.imageMgr().close(state.idPlayerImage);
logTaskOk(mLog);
mLog.msg(LL_INFO, " Close remaining images ... ");
mC64.imageMgr().close(0);
logTaskOk(mLog);
Main::terminate();

Complete source

The tutorial source is authoritative. The following listing is included directly from validation/source/Tutorial_01_Basic.cpp.

/* ----------------------------------------------------------------------
CRM64Pro GDK - Roberto Prieto
Copyright (C) 2013-2026 MegaStorm Systems
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
------------------------------------------------------------------------
Tutorial 01: Basic
------------------------------------------------------------------------
Overview:
This tutorial opens a window, loads two images, moves a ship with the
keyboard, and saves a screenshot.
Key concepts:
- Start the CRM64Pro memory manager.
- Access the main engine object and managers.
- Configure log output, timer and screen.
- Load PNG images with ImageMgr.
- Read SDL keyboard and mouse events through Main::update().
- Update movement at a fixed logic rate.
- Render images from the main loop.
- Save the current screen as a PNG file.
Controls:
- Cursor Keys: Move the ship image.
- S: Save a screen snapshot.
- Any Key/Mouse: Logs events.
- Q / ESC: Quit.
Loop order:
- Process input events.
- Run one fixed logic update.
- Render the background and moving ship image.
------------------------------------------------------------------------ */
#include "CRM64Pro.h"
#include "RunParameter.h"
using namespace CRM64Pro;
#define BASEDIR "Base/"
#ifdef CRM64PRO_PLATFORM_WINDOWS
#define OUTPUTDIR "Win64/"
#elif defined(CRM64PRO_PLATFORM_LINUX)
#define OUTPUTDIR "Linux/"
#elif defined(CRM64PRO_PLATFORM_MACOS)
#define OUTPUTDIR "macOS/"
#endif
#define RESOURCE_BG_IMAGE BASEDIR"tutorial_bg.png"
#define RESOURCE_PLAYER_IMAGE BASEDIR"tutorial_ship.png"
#define OUTPUT_SNAPSHOT OUTPUTDIR"Tutorial_01_Basic-Snapshot.png"
// Fixed-rate timing.
// This first tutorial updates and renders once per fixed-rate step.
static const Sint32 iLogicRate = 20;
static const Sint32 iRenderRate = iLogicRate;
// Window size and movement speed.
static const Sint32 iScreenW = 960;
static const Sint32 iScreenH = 540;
static const float fMoveSpeed = 220.0f;
// Values changed while the tutorial runs.
struct TutorialState
{
Sint32 idBgImage = -1;
Sint32 idPlayerImage = -1;
float fPlayerX = 386.0f;
float fPlayerY = 186.0f;
bool bMoveLeft = false;
bool bMoveRight = false;
bool bMoveUp = false;
bool bMoveDown = false;
};
// Keep a value inside the given range.
static float clampFloat(float fValue, float fMin, float fMax)
{
if(fValue < fMin) return fMin;
if(fValue > fMax) return fMax;
return fValue;
}
// Helper functions used by the setup log messages.
static void logTaskOk(Log& mLog)
{
mLog.msg(LL_DEBUG, "OK\n");
}
// Record a failed tutorial task.
static void logTaskFailed(Log& mLog, Sint32 iCode)
{
mLog.msg(LL_ERROR, "FAILED (Code %d)\n", iCode);
}
// Record a failed tutorial task.
static void logTaskFailed(Log& mLog)
{
mLog.msg(LL_ERROR, "FAILED\n");
}
// Move the ship image one fixed logic step.
static void updateLogic(TutorialState& rState, Image* pPlayerImage, float fDeltaTime)
{
if(!pPlayerImage) return;
float fDX = 0.0f;
float fDY = 0.0f;
if(rState.bMoveLeft) fDX -= fMoveSpeed * fDeltaTime;
if(rState.bMoveRight) fDX += fMoveSpeed * fDeltaTime;
if(rState.bMoveUp) fDY -= fMoveSpeed * fDeltaTime;
if(rState.bMoveDown) fDY += fMoveSpeed * fDeltaTime;
const float fMaxX = static_cast<float>(iScreenW - pPlayerImage->getWidth());
const float fMaxY = static_cast<float>(iScreenH - pPlayerImage->getHeight());
rState.fPlayerX = clampFloat(rState.fPlayerX + fDX, 0.0f, fMaxX);
rState.fPlayerY = clampFloat(rState.fPlayerY + fDY, 0.0f, fMaxY);
}
// Draw the current frame.
// This first tutorial renders from main(). The next tutorials move rendering
// into a Screen render callback.
static void renderFrame(Image* pBgImage, Image* pPlayerImage, const TutorialState& rState)
{
if(pBgImage) pBgImage->render();
if(pPlayerImage)
{
SDL_FRect rDst = {
rState.fPlayerX,
rState.fPlayerY,
static_cast<float>(pPlayerImage->getWidth()),
static_cast<float>(pPlayerImage->getHeight())
};
pPlayerImage->render(0, nullptr, &rDst);
}
}
// Run the tutorial application and release its resources.
int main(int argc, char* argv[])
{
if(!runParameterReadRender(argc, argv, eRenderer)) return 1;
// Start CRM64Pro memory tracking before creating engine resources.
// atexit() releases memory tracking data when the program exits.
atexit(CMem::destroy);
// Main gives access to the CRM64Pro managers.
Main& mC64 = Main::instance();
Log& mLog = *mC64.logMgr().get();
TutorialState state;
// Write log output to stdout and to a file under validation/bin.
mLog.init("Tutorial_01_Basic", LL_DEBUG, LM_FILE | LM_STDOUT, OUTPUTDIR"Tutorial_01_Basic.log");
mLog.msg(LL_INFO, "\nSETUP: screen and timing\n");
// Initialize the timer before calling Main::update().
// setRate() receives render frames per second, then logic frames per second.
mLog.msg(LL_INFO, " Initialize timer ... ");
if(!mC64.timer().init())
{
logTaskFailed(mLog);
return -1;
}
logTaskOk(mLog);
mLog.msg(LL_INFO, " Set frame rates (render=%d, logic=%d) ... ", iRenderRate, iLogicRate);
if(!mC64.timer().setRate(iRenderRate, iLogicRate))
{
logTaskFailed(mLog);
return -1;
}
logTaskOk(mLog);
// Add a 1 ms idle delay inside Main::update().
// Configure and show the default screen.
Screen* pScreen = mC64.configMgr().get();
pScreen->setSize(iScreenW, iScreenH);
pScreen->setDriver(eRenderer);
pScreen->setTitle("CRM64Pro - Tutorial 01: Basic");
mLog.msg(LL_INFO, " Create screen (%dx%d) ... ", iScreenW, iScreenH);
if(pScreen->show() < 0)
{
mLog.msg(LL_CRITICAL, "FAILED\n");
// Standard setup error path:
// 1. Log what failed.
// 2. Terminate the engine so initialized managers are cleaned up.
// 3. Return -1 to report application failure to the operating system.
return -1;
}
logTaskOk(mLog);
mLog.msg(LL_INFO, "\nRESOURCES: external images\n");
// Load external PNG images from validation/bin/Base.
// The second parameter is the resource name stored by ImageMgr.
mLog.msg(LL_INFO, " Load background image: %s ... ", RESOURCE_BG_IMAGE);
state.idBgImage = mC64.imageMgr().loadFromFile(RESOURCE_BG_IMAGE, "tutorialBasicBg");
if(state.idBgImage < 0)
{
logTaskFailed(mLog, state.idBgImage);
return -1;
}
logTaskOk(mLog);
mLog.msg(LL_INFO, " Load ship image: %s ... ", RESOURCE_PLAYER_IMAGE);
state.idPlayerImage = mC64.imageMgr().loadFromFile(RESOURCE_PLAYER_IMAGE, "tutorialBasicPlayer");
if(state.idPlayerImage < 0)
{
logTaskFailed(mLog, state.idPlayerImage);
return -1;
}
logTaskOk(mLog);
mLog.msg(LL_INFO, " Access background image object ... ");
Image* pBgImage = mC64.imageMgr().get(state.idBgImage);
if(pBgImage == nullptr)
{
logTaskFailed(mLog);
return -1;
}
logTaskOk(mLog);
mLog.msg(LL_INFO, " Access ship image object ... ");
Image* pPlayerImage = mC64.imageMgr().get(state.idPlayerImage);
if(pPlayerImage == nullptr)
{
logTaskFailed(mLog);
return -1;
}
logTaskOk(mLog);
mLog.msg(LL_INFO, "\nCONTROLS\n");
mLog.msg(LL_INFO, " [Q] / [ESC] Quit\n");
mLog.msg(LL_INFO, " [Arrow Keys] Move the ship image\n");
mLog.msg(LL_INFO, " [S] Save a screen snapshot\n");
mLog.msg(LL_INFO, " Any key or mouse button logs the input event\n");
mLog.msg(LL_INFO, "\nRUNNING\n");
SDL_Event event;
bool bRunning = true;
while(bRunning)
{
// Main::update() returns 1 while input and render processing continues.
// It returns 0 when the next fixed logic step is ready.
while(mC64.update(&event))
{
if(event.type == SDL_EVENT_QUIT)
{
bRunning = false;
}
else if(event.type == SDL_EVENT_KEY_DOWN)
{
// SDL3 stores the key value in event.key.key.
mLog.msg(LL_INFO, " Key pressed: %s (%d)\n", SDL_GetKeyName(event.key.key), event.key.key);
if(event.key.key == SDLK_Q || event.key.key == SDLK_ESCAPE)
{
bRunning = false;
}
else if(event.key.key == SDLK_LEFT)
{
state.bMoveLeft = true;
}
else if(event.key.key == SDLK_RIGHT)
{
state.bMoveRight = true;
}
else if(event.key.key == SDLK_UP)
{
state.bMoveUp = true;
}
else if(event.key.key == SDLK_DOWN)
{
state.bMoveDown = true;
}
else if(event.key.key == SDLK_S)
{
mLog.msg(LL_INFO, " Save screen snapshot: %s ... ", OUTPUT_SNAPSHOT);
if(pScreen->saveSnapshot(OUTPUT_SNAPSHOT) == 0)
{
logTaskOk(mLog);
}
else
{
logTaskFailed(mLog);
}
}
}
else if(event.type == SDL_EVENT_KEY_UP)
{
if(event.key.key == SDLK_LEFT) state.bMoveLeft = false;
else if(event.key.key == SDLK_RIGHT) state.bMoveRight = false;
else if(event.key.key == SDLK_UP) state.bMoveUp = false;
else if(event.key.key == SDLK_DOWN) state.bMoveDown = false;
}
else if(event.type == SDL_EVENT_MOUSE_BUTTON_DOWN)
{
mLog.msg(LL_INFO, " Mouse clicked: button %d at %d, %d\n", event.button.button, (Sint32)event.button.x, (Sint32)event.button.y);
}
}
if(!bRunning) break;
updateLogic(state, pPlayerImage, 1.0f / static_cast<float>(iLogicRate));
renderFrame(pBgImage, pPlayerImage, state);
}
mC64.imageMgr().info();
// Close one image by id, then close the remaining ImageMgr resources.
// close(0) closes all resources owned by that manager.
mLog.msg(LL_INFO, "\nCLEANUP\n");
mLog.msg(LL_INFO, " Close ship image by id ... ");
mC64.imageMgr().close(state.idPlayerImage);
logTaskOk(mLog);
mLog.msg(LL_INFO, " Close remaining images ... ");
mC64.imageMgr().close(0);
logTaskOk(mLog);
return 0;
}
Screen * get(Sint32 idScreen=0)
Get a pointer to the screen using its handle.
Definition CoreConfig.cpp:1497
void setMTFriendly(Uint8 iDelayMS)
Set the multithread-friendly scheduler yield.
Definition CoreConfig.cpp:1183
Image Object class.
Definition CRM64Pro.h:3356
Sint32 getHeight() const
Get the image height.
Definition GraphicsImage.cpp:1839
Sint32 getWidth() const
Get the image width.
Definition GraphicsImage.cpp:1833
Sint32 render(Sint32 idRes=0, SDL_FRect *pSrc=nullptr, SDL_FRect *pDst=nullptr)
Render the image.
Definition GraphicsImage.cpp:1575
Image * get(Sint32 idImg)
Get a pointer to the image using its handle.
Definition GraphicsImage.cpp:2279
Sint32 loadFromFile(const string &sFile, const string &sName="")
Load an image from an external file (BMP, PNG, JPG, PCX, TGA or WebP formats).
Definition GraphicsImage.cpp:2434
bool info(Sint32 iMode=0) override
Request Image Manager information.
Definition GraphicsImage.cpp:2094
Sint32 close(Sint32 idImg) override
Close and destroy an image.
Definition GraphicsImage.cpp:2178
Log Object class.
Definition CRM64Pro.h:771
CRM64Pro GDK Main class.
Definition CRM64Pro.h:502
Screen Object class.
Definition CRM64Pro.h:1055
Sint32 saveSnapshot(const string &sFile)
Save a screen snapshot to an external PNG file.
Definition CoreConfig.cpp:740
Sint32 show()
Show the screen.
Definition CoreConfig.cpp:362
Sint32 setDriver(eConfigRendererDriver eCRD)
Set the renderer driver.
Definition CoreConfig.cpp:454
Sint32 setSize(Sint32 iWidth, Sint32 iHeight)
Set the size of the screen.
Definition CoreConfig.cpp:526
bool setTitle(const string &sName)
Set the title.
Definition CoreConfig.cpp:674
void setStatsLevel(eMemStatsLevel eMSL)
Set the memory stats gathering level.
Definition CMemoryManager.cpp:618
void destroy()
Releases the internal heap and displays final stats.
Definition CMemoryManager.cpp:954
@ MSL_NORMAL
Collect allocations per module (CRM64Pro and user). Default for debug builds.
Definition CRM64Pro.h:386
eConfigRendererDriver
Screen renderer drivers.
Definition CRM64Pro.h:1013
@ CRD_SOFTWARE
Screen::setDriver(): software renderer driver. Slow but works on all platforms.
Definition CRM64Pro.h:1015
Log * get(Sint32 idLog=0)
Get a pointer to the log object.
Definition CoreLog.cpp:921
@ LM_FILE
Log output mode for the 'lm' parameter in CRM64Pro::Log::init(). Output to a file and overwrite exist...
Definition CRM64Pro.h:748
@ LM_STDOUT
Log output mode for the 'lm' parameter in CRM64Pro::Log::init(). Output to standard output (stdout).
Definition CRM64Pro.h:750
@ LL_INFO
Runtime events (startup/shutdown). Messages without timestamp.
Definition CRM64Pro.h:764
@ LL_DEBUG
Detailed information for flow control.
Definition CRM64Pro.h:765
@ LL_CRITICAL
Fatal errors, application crash, or assertions.
Definition CRM64Pro.h:761
@ LL_ERROR
Runtime errors that do not require immediate termination.
Definition CRM64Pro.h:762
Timer & timer()
Get reference to Timer module.
Definition CoreMain.cpp:730
Sint32 update(SDL_Event *evUser=nullptr)
Manage the GDK update cycle with a fixed virtual logic frame rate.
Definition CoreMain.cpp:451
ImageMgr & imageMgr()
Get reference to Image Manager.
Definition CoreMain.cpp:754
static void terminate()
Main explicit destructor.
Definition CoreMain.cpp:266
static Main & instance()
Access the Main singleton.
Definition CoreMain.cpp:252
LogMgr & logMgr()
Get reference to Log Manager.
Definition CoreMain.cpp:724
ConfigMgr & configMgr()
Get reference to Config Manager.
Definition CoreMain.cpp:712
bool init(eTimerState eState=TS_INIT)
Initialize the timer system.
Definition CoreTimer.cpp:543
bool setRate(Uint16 iR, Uint16 iL)
Set preferred Render and Logic Frame Rate.
Definition CoreTimer.cpp:556
CRM64Pro GDK.
Definition AudioTrack.cpp:36

Navigation

Back to the tutorials index

The next tutorial moves rendering into a callback, stores image resources in a CDC archive and adds the debug window and built-in console.

Continue with Tutorial 02: System services