🐣 Mobile Eggbert

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, …
SharpRuntime Dependency Rule If a .NET BCL type is needed by this project or CNA, it must be added to SharpRuntime — not worked around inline. Raw C++ types must never appear on the XNA API surface. See sharp-runtime.

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

ClassFileRole
Game1Game1.hpp/cppTop-level XNA game; phase state machine; owns all subsystems
DecorDecor.hpp/cppFull gameplay simulation (~9400 lines): world, player, AI, physics, rendering
PixmapPixmap.hpp/cppSprite rendering via CNA SpriteBatch; manages 17 channels
SoundSound.hpp/cppAudio playback (volume/balance tables, 93 sound slots)
InputPadInputPad.hpp/cppTouch, keyboard, and accelerometer input abstraction
GameDataGameData.hpp/cppPersistent save data (640-byte binary, 3 gamer slots)
TablesTables.hpp/cppStatic animation table (2911 entries) + cheat code list
WorldsWorlds.hpp/cppLevel and save-game file I/O
TextText.hpp/cppBitmap font renderer (32×32 px cells from text.png)
JaugeJauge.hpp/cppHUD gauge bar (health / lives display)
SliderSlider.hpp/cppUI slider widget (settings screen)
MyResourceMyResource.hpp/cppLocalized strings in French, English, German
TinyPointTinyPoint.hpp/cpp2D integer point (x, y)
TinyRectTinyRect.hpp/cpp2D integer rectangle — non-standard field order: L, R, T, B
MiscMisc.hpp/cppGeometry helper functions
HelperHelper.hpp/cppString formatting utilities
TinyRect Field Order Warning 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:

MethodCalledResponsibility
Initialize()Once at startupPlatform/window setup, subsystem creation
LoadContent()After InitializeAsset loading via CNA content pipeline
Update()Every frameInput polling, phase state machine, game logic
Draw()Every frameSpriteBatch rendering pass

Game1 Subsystem Members

MemberTypeRole
graphicsGraphicsDeviceManagerDisplay/window management (from CNA)
pixmapshared_ptr<IPixmap>Sprite rendering
soundshared_ptr<ISound>Audio playback
decorDecorGameplay simulation
inputPadInputPadTouch/keyboard/accelerometer input
gameDataGameDataPersistent save data
waitJaugeJaugeLoading 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 Cellule structs
  • 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:

InterfaceConcrete Implementation
IPixmapPixmap (CNA SpriteBatch renderer)
ISoundSound (CNA audio via SDL3_mixer)
IGame1Game1 (main game instance)