Architecture Overview
Free Eggbert's architecture closely mirrors the original Win32/DirectX 3 game structure, reconstructed from binary analysis. The codebase is structured as a set of cooperating C++ classes managed through a classic Win32 application model.
Layered Architecture
┌──────────────────────────────────────┐
│ Game Logic (C++20) │
│ blupi.cpp / CDecor / CEvent / … │
├──────────────────────────────────────┤
│ Free API (Win32 → cross-platform) │
│ Free Direct (DirectX → SDL3) │
├──────────────────────────────────────┤
│ SDL3 / SDL_image / SDL_mixer │
└──────────────────────────────────────┘
Game code only includes WinAPI-like and DirectX-like compatibility headers
(windows.h, ddraw.h, dsound.h, etc.).
SDL is never included directly by game source files.
Main Entry Point
Source file: src/blupi.cpp
Entry function: WinMain() (Win32-style)
blupi.cpp contains the application bootstrap, window creation,
message loop, and top-level object instantiation.
Initialization Sequence
- Create the application window
- Instantiate CPixmap — DirectDraw surface manager
- Call
CPixmap::Create()— initialize display surfaces - Call
CPixmap::CacheAll(TRUE, …)— load all image assets - Instantiate CSound — audio system
- Instantiate CNetwork — DirectPlay (fails silently in most configs)
- Instantiate CDecor — game world and logic engine
- Instantiate CEvent — input handler and game phase dispatcher
- Start multimedia timer for game tick updates
- Enter the main message loop
CPixmap::Create() twice during startup —
once directly, and once inside CPixmap::CacheAll(TRUE, …).
This is a suspected decompilation artifact. Real DirectDraw may reject the
second initialization. See Known Issues.
Main Game Loop
The application uses a classic Win32 message loop with a multimedia timer:
// WinMain (blupi.cpp) — simplified
g_updateTimer = timeSetEvent(g_timerInterval, g_timerInterval / 4,
TimerStep, NULL, TIME_PERIODIC);
while (TRUE) {
if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) {
if (!GetMessage(&msg, NULL, 0, 0))
return msg.wParam;
TranslateMessage(&msg);
DispatchMessage(&msg);
} else {
if (!g_bActive) WaitMessage();
}
}
The timer callback posts update messages. The window procedure handles
WM_UPDATE by calling:
UpdateFrame();
SetDecor();
g_pPixmap->Display();
Core Classes
| Class | Header | Source(s) | Responsibility |
|---|---|---|---|
CDecor |
include/decor.hpp |
src/decor*.cpp |
Central game engine — world state, all game logic |
CEvent |
include/event.hpp |
src/event.cpp |
Input handling, game phase dispatch, keyboard/mouse |
CPixmap |
include/pixmap.hpp |
src/pixmap.cpp |
DirectDraw surface manager, sprite blitting |
CSound |
include/sound.hpp |
src/sound.cpp, src/soundbass.cpp |
Audio playback — DirectSound or BASS backend |
CNetwork |
include/network.hpp |
src/network.cpp |
DirectPlay session management, multiplayer |
CButton |
include/button.hpp |
src/button.cpp |
UI button rendering and hit-testing |
CJauge |
include/jauge.hpp |
src/jauge.cpp |
Progress/gauge bar rendering |
CMenu |
include/menu.hpp |
src/menu.cpp |
Menu rendering and navigation |
CDecor Source File Decomposition
CDecor is the most important class. Its implementation is split
across 8 source files by responsibility:
| File | Responsibility |
|---|---|
src/decor.cpp | Initialization, rendering, main step loop, region/music |
src/decblupi.cpp | Player movement, jumping, vehicle logic, physics |
src/decblock.cpp | Block/crate interaction, push/pull, door logic |
src/decmove.cpp | Moving object (enemy/bomb/effect) step logic |
src/decnet.cpp | Network game synchronization and event dispatch |
src/decdesign.cpp | Level editor — place/remove tiles and objects |
src/decio.cpp | Save/load game state to .blp files |
src/dectables.cpp | Static lookup tables for decor |
World Grid System
The game world is a 100×100 grid of cells. Each cell stores a sprite index into the background/decor spritesheet.
- Grid dimensions:
MAXCELX×MAXCELY= 100×100 - Object sprites: 64×64 px (
DIMOBJX,DIMOBJY) - Player sprites: 60×60 px (
DIMBLUPIX,DIMBLUPIY) - Explosion sprites: 128×128 px (
DIMEXPLOX,DIMEXPLOY)
Render Channel System
CPixmap manages 15 independent DirectDraw surfaces,
each identified by a channel constant. Layers are composited in order to build the
final frame:
| Channel | Value | Content |
|---|---|---|
CHBACK | 0 | Background terrain |
CHOBJECT | 1 | Foreground objects and pickups |
CHBLUPI | 2 | Player character |
CHDECOR | 3 | Decorative overlays |
CHBUTTON | 4 | UI buttons |
CHJAUGE | 5 | Gauge/progress bars |
CHTEXT | 6 | Normal text characters |
CHLITTLE | 7 | Small text characters |
CHMAP | 8 | Minimap |
CHEXPLO | 9 | Explosion sprites |
CHELEMENT | 10 | Particle/element effects |
CHBLUPI1–3 | 11–13 | Player character variants (multiplayer) |
CHTEMP | 14 | Temporary scratch surface |
See Image Channels for the full reference.
Game Phase System
Game state is controlled by game phases, dispatched as Windows messages
(WM_USER + N) and handled by CEvent. Examples:
WM_PHASE_INIT— startup initializationWM_PHASE_PLAY— normal gameplayWM_PHASE_WIN/WM_PHASE_LOST— end of levelWM_PHASE_SETUP— settings screenWM_PHASE_BUILD— level editorWM_PHASE_SERVICE/SESSION/MULTI— multiplayer lobby
See Game Phases Reference for all 60+ phases.
Moving Object System
Up to 200 moving objects (MAXMOVEOBJECT) can be active
simultaneously. They are tracked in a fixed-size MoveObject[200] array
within CDecor. Each object has a type (TYPE_*),
position, animation state, and motion trajectory.
Object types include enemies (fish, bird, wasp), vehicles, bombs, collectibles, and visual effects. See Object Types.
Player State
Unlike the Planet Blupi engine which uses a Blupi[100] array,
Free Eggbert stores the player state as individual member fields directly in
CDecor (m_blupiPos, m_blupiAction,
m_blupiDir, etc.).
In multiplayer, up to 4 players are tracked via network packets.
Audio Architecture
Audio is managed by CSound with two selectable backends
controlled by the _BASS compile flag:
- Default (
_BASS=FALSE):src/sound.cpp— DirectSound/MCI path - BASS library (
_BASS=TRUE):src/soundbass.cpp— BASS + BASSMIDI
See Audio System for full documentation.