CEvent

Header: include/event.hpp
Implementation: src/event.cpp

⚠️
event.cpp is identified as the most complex and incomplete source file in the project. It requires the most work of all files and is the top debugging priority.

CEvent is the main game controller. It sits at the top of the game stack, receiving all Windows messages and routing them to the appropriate subsystem. It implements the game phase dispatch loop, coordinates input, drives the render/update cycle, and manages transitions between screens and modes.

Responsibilities

  • Receives all Win32 messages from WinProc() in blupi.cpp
  • Dispatches WM_PHASE_* messages to phase-specific handlers
  • Reads keyboard and mouse input each tick
  • Converts raw input into KEY_* bitmasks and sends them to CDecor::SetInput()
  • Drives the main game timer and tick loop
  • Manages menu navigation, UI interaction, and screen transitions
  • Coordinates with CDecor, CPixmap, CSound, and CNetwork

Game Phase Dispatch

The game is divided into over 60 phases, each represented as a WM_PHASE_* constant. CEvent maintains the current phase and routes each WM_USER + N message to the handler for phase N.

See Game Phases Reference for the complete WM_PHASE_* table.

// Message loop pseudocode
switch (message) {
  case WM_PHASE_PLAY:    HandlePlay();    break;
  case WM_PHASE_MENU:    HandleMenu();    break;
  case WM_PHASE_PAUSE:   HandlePause();   break;
  // ... 60+ more phases
}

Input Flow

  1. OS delivers keyboard/mouse events to WinProc()
  2. CEvent accumulates key state into a KEY_* bitmask each tick
  3. Bitmask is passed to CDecor::SetInput(keys)
  4. CDecor applies the input to player physics in the next MoveStep()
  5. Mouse position drives UI interaction inside CEvent phase handlers

See KEY_* bitmask values and Input System for more detail.

Game Timer

CEvent controls the game timer. On each Windows timer tick, it calls CDecor::MoveStep() to advance the simulation and then calls CDecor::Build() to render the updated world. The timer tick interval is set in config.def via the Timer key (10–1000 ms); the speed multiplier via SpeedRate (1–2).

Platform Notes

On WebAssembly (Emscripten), the blocking Win32 message loop is replaced by Emscripten's main-loop callback. The phase dispatch and input handling remain the same; only the loop driver changes.

On Android, touch events are mapped to mouse/keyboard equivalents before being fed into CEvent's normal input path.