Architecture
Mobile Eggbert follows the XNA Game class model: a single Game1 object owns all subsystems and drives the game loop via Initialize / LoadContent / Update / Draw.
Dependency Overview
WindowsPhoneSpeedyBlupi (this project)
│
├── CNA (/rv/data/development/github.com/openeggbert/cna)
│ │
│ └── SDL3, SDL3_image, SDL3_mixer
│
└── SharpRuntime (/rv/data/development/github.com/openeggbert/sharp-runtime)
└── System.Math, System.String, List<T>, Dictionary, EventHandler, …
Source Layout
mobile-eggbert/
├── include/WindowsPhoneSpeedyBlupi/ ← all .hpp headers
│ ├── ConfigDef.hpp ← LEGACY vs MODERN mode selection
│ ├── Config.hpp ← FPS, time/speed/resolution scaling
│ ├── Decor.hpp ← core game simulation (player, world, AI)
│ ├── Def.hpp ← global constants (LXIMAGE, MAXCELX, …)
│ ├── Game1.hpp ← main XNA game class
│ ├── GameData.hpp ← save data serialization
│ ├── Helper.hpp ← string formatting utilities
│ ├── IGame1.hpp ← interface for game instance
│ ├── InputPad.hpp ← touch/keyboard/accelerometer input
│ ├── IPixmap.hpp ← interface for sprite rendering
│ ├── ISound.hpp ← interface for audio playback
│ ├── Jauge.hpp ← HUD gauge widget
│ ├── Misc.hpp ← geometry helpers
│ ├── MyResource.hpp ← localized UI strings (FR/EN/DE)
│ ├── Pixmap.hpp ← CNA/SpriteBatch sprite renderer
│ ├── Slider.hpp ← UI slider widget
│ ├── Sound.hpp ← CNA audio playback
│ ├── Tables.hpp ← static animation/data tables
│ ├── Text.hpp ← bitmap font renderer
│ ├── TinyPoint.hpp ← 2D integer point
│ ├── TinyRect.hpp ← 2D integer rectangle (L,R,T,B order!)
│ ├── Worlds.hpp ← world file I/O
│ ├── def/ ← enumeration headers
│ │ ├── BlupiAction.hpp ← 88 player animation states
│ │ ├── ContinueMission.hpp ← checkpoint/resume states
│ │ ├── Direction.hpp ← None/Left/Right
│ │ ├── GameSpeed.hpp ← Slow/Normal/Fast/Faster/Fastest
│ │ ├── KeyPressFlags.hpp ← Jump/Fire/Down bitmask
│ │ ├── PixmapChannel.hpp ← 17 sprite-sheet channels
│ │ ├── SecretPower.hpp ← 5 active power-up states
│ │ ├── SoundChannel.hpp ← 93 sound effect slots
│ │ └── Zoom.hpp ← 4 zoom levels (MODERN mode)
│ └── decor/ ← Decor-specific enum headers
│ ├── DecorAction.hpp ← camera-shake action types
│ ├── DoorKeyFlags.hpp ← 3-key bitmask
│ └── ObjectType.hpp ← 203+ moving object types
└── src/WindowsPhoneSpeedyBlupi/ ← all .cpp implementations
Key Classes
| Class | File | Role |
|---|---|---|
Game1 | Game1.hpp/cpp | Top-level XNA game; phase state machine; owns all subsystems |
Decor | Decor.hpp/cpp | Full gameplay simulation (~9400 lines): world, player, AI, physics, rendering |
Pixmap | Pixmap.hpp/cpp | Sprite rendering via CNA SpriteBatch; manages 17 channels |
Sound | Sound.hpp/cpp | Audio playback (volume/balance tables, 93 sound slots) |
InputPad | InputPad.hpp/cpp | Touch, keyboard, and accelerometer input abstraction |
GameData | GameData.hpp/cpp | Persistent save data (640-byte binary, 3 gamer slots) |
Tables | Tables.hpp/cpp | Static animation table (2911 entries) + cheat code list |
Worlds | Worlds.hpp/cpp | Level and save-game file I/O |
Text | Text.hpp/cpp | Bitmap font renderer (32×32 px cells from text.png) |
Jauge | Jauge.hpp/cpp | HUD gauge bar (health / lives display) |
Slider | Slider.hpp/cpp | UI slider widget (settings screen) |
MyResource | MyResource.hpp/cpp | Localized strings in French, English, German |
TinyPoint | TinyPoint.hpp/cpp | 2D integer point (x, y) |
TinyRect | TinyRect.hpp/cpp | 2D integer rectangle — non-standard field order: L, R, T, B |
Misc | Misc.hpp/cpp | Geometry helper functions |
Helper | Helper.hpp/cpp | String formatting utilities |
TinyRect fields are in non-standard order: Left, Right, Top, Bottom
(not Left, Top, Right, Bottom as in most frameworks).
The constructor is TinyRect(left, right, top, bottom). Passing arguments in the wrong order
causes silent geometry bugs.
Game1 — XNA Game Loop
Game1 inherits CNA's Game base class and follows the standard XNA lifecycle:
| Method | Called | Responsibility |
|---|---|---|
Initialize() | Once at startup | Platform/window setup, subsystem creation |
LoadContent() | After Initialize | Asset loading via CNA content pipeline |
Update() | Every frame | Input polling, phase state machine, game logic |
Draw() | Every frame | SpriteBatch rendering pass |
Game1 Subsystem Members
| Member | Type | Role |
|---|---|---|
graphics | GraphicsDeviceManager | Display/window management (from CNA) |
pixmap | shared_ptr<IPixmap> | Sprite rendering |
sound | shared_ptr<ISound> | Audio playback |
decor | Decor | Gameplay simulation |
inputPad | InputPad | Touch/keyboard/accelerometer input |
gameData | GameData | Persistent save data |
waitJauge | Jauge | Loading progress gauge (Wait phase) |
Decor — Core Gameplay
Decor.cpp is the largest file (~9400+ lines). It contains the entire gameplay simulation and is responsible for:
- World grid management — two 100×100 arrays of
Cellulestructs - Player physics: walking, jumping, swimming, climbing bars
- Vehicle logic: helicopter, jeep, tank, hovercraft, skateboard
- Moving object AI: enemies, bombs, lifts, conveyors (up to 200 concurrent)
- Collision detection against tile icons (
IsLave(),IsDeepWater(),IsDoor(), …) - Camera scrolling and shake
- Rendering:
Build()draws tiles,DrawInfo()draws HUD - Level load/save delegation to
Worlds - Win/loss detection
World Grid Data Structures
struct Cellule {
short icon; // sprite index into background/decor sheet
};
// Two 100×100 grids:
Cellule m_decor[100][100]; // base tile layer (terrain, hazards)
Cellule m_bigDecor[100][100]; // secondary decorative layer
Moving Objects
// Up to 200 concurrent moving objects
struct MoveObject {
ObjectType type; // what kind of object
short stepAdvance;
short stepRecede;
short timeStopStart;
short timeStopEnd;
TinyPoint posStart; // starting position (tile coords)
TinyPoint posEnd; // target/end position
TinyPoint posCurrent; // current position
short step; // current animation step
short time; // timer
short phase; // current motion phase
short channel; // sprite channel
short icon; // sprite icon index
};
Tables System
Tables.cpp contains a 2911-element static animation table that maps each (BlupiAction, phase) pair to a (channel, icon, nextPhase) tuple. This drives all character animation without per-action if/else logic in Decor.cpp.
The table also contains the list of 22 cheat code strings used by Game1::CheatAction().
Interfaces
Pixmap and Sound are accessed through abstract interfaces, allowing platform-specific or test implementations:
| Interface | Concrete Implementation |
|---|---|
IPixmap | Pixmap (CNA SpriteBatch renderer) |
ISound | Sound (CNA audio via SDL3_mixer) |
IGame1 | Game1 (main game instance) |