v0.3.0: display abstraction, map-browser menu, SAGE terrain tiling/blends
- ra3.client::display: shared interactive loops; SDL and Vulkan backends implement only the primitives (init/present/poll_event/window_size/ key_down/present_terrain). ra3.display picks the backend. - Menu: maps by localized name (gamestrings.csf), red/gold theme, hover highlight, mouse + keyboard, wheel scroll, fullscreen and FPS/vsync options, loading progress bar. - Terrain: continuous tile sampling via a texture array (REPEAT, uv = cell/(2*cellSize)) removes per-cell grid seams; SAGE blend ramp for material transitions; FPS label + top-right minimap overlays. - Skip the skirmish sim for map views; reuse the Vulkan texture; no idle terrain redraw.
This commit is contained in:
+56
-20
@@ -15,19 +15,36 @@ with llvm-mingw for Windows.
|
||||
└───────────────────┬───────────────────┘
|
||||
┌──────────────┬───────────────┼───────────────┬──────────────┐
|
||||
▼ ▼ ▼ ▼ ▼
|
||||
ra3.ui ra3.render ra3.skirmish ra3.client ra3.game
|
||||
SDL3 window framebuffer match rules display/loop RA3 sides
|
||||
ra3.display ra3.render ra3.skirmish ra3.client ra3.game
|
||||
backend pick framebuffer match rules display+loops RA3 sides
|
||||
│ │ │ │ │
|
||||
└──────┬───────┘ └───────┬───────┘ │
|
||||
▼ ▼ │
|
||||
ra3.core ra3.logic │
|
||||
simulation │
|
||||
┌───────────────────────────────────────┬──────────────────────┘
|
||||
▼ ▼
|
||||
ra3.map ra3.fs
|
||||
map catalog BIG4 + RefPack
|
||||
┌──┴───┐ │ └───────┬───────┘ │
|
||||
▼ ▼ ▼ ▼ │
|
||||
ra3.ui ra3.vulkan ra3.terrain ra3.logic │
|
||||
SDL Vulkan heightmap/blends simulation │
|
||||
┌──────────────────────┘
|
||||
▼
|
||||
ra3.map / ra3.fs
|
||||
catalog / BIG4 + RefPack
|
||||
```
|
||||
|
||||
## Presentation layer
|
||||
|
||||
`ra3.client::display` is the single seam between the engine and the windowing
|
||||
stack. A backend implements only the low-level primitives (`init`, `present`,
|
||||
`poll_event`, `window_size`, `key_down`, `shutdown`) and, optionally,
|
||||
`present_terrain`; the interactive loops (menu, image viewer, camera viewer,
|
||||
GPU terrain) and the native-to-`ui_event` mapping live once in the base class,
|
||||
so the SDL and Vulkan paths cannot drift. SDL3 remains the platform layer (it
|
||||
owns the window, input and the low-cost blit backend); Vulkan is the accelerated
|
||||
backend. `ra3.display` selects the first backend that starts, and the app never
|
||||
references a backend by name.
|
||||
|
||||
The Vulkan backend currently hand-rolls its pipelines. As materials, skybox and
|
||||
HUD arrive, a thin RHI + render-graph belongs between `ra3.client` and the
|
||||
Vulkan/SDL backends; `present_terrain` is the placeholder for that step.
|
||||
|
||||
|
||||
## Module responsibilities
|
||||
|
||||
### `ra3.core`
|
||||
@@ -44,9 +61,20 @@ spatial grid, and the 30 Hz `game_logic` driver (`prepare_new_game` /
|
||||
`start_new_game` / `update`).
|
||||
|
||||
### `ra3.client`
|
||||
The presentation boundary: an abstract `display` with a `headless_display`
|
||||
implementation, and `game_client`, the seam a future W3D/D3D9 renderer plugs
|
||||
into.
|
||||
The presentation boundary: the abstract `display` (low-level primitives plus the
|
||||
shared interactive loops and `ui_event` mapping), a `headless_display` for
|
||||
CPU-only runs, and `game_client`, the facade that owns the simulation and drives
|
||||
the frame loop.
|
||||
|
||||
### `ra3.display`
|
||||
Backend selection: tries Vulkan, then SDL, then reports failure so the caller can
|
||||
fall back to an offscreen image. The only module that names a concrete backend.
|
||||
|
||||
### `ra3.terrain`
|
||||
The real map terrain: parses `CkMp`'s `HeightMapData` and `BlendTileData`
|
||||
(tiles, `Blends`/`ThreeWayBlends` and their `BlendDescription`s), loads the
|
||||
`Terrain.big` tile textures, and rasterises the map (software `render`/`render3d`
|
||||
and the GPU `gpu_terrain` for `present_terrain`).
|
||||
|
||||
### `ra3.game`
|
||||
Red Alert 3 data that SAGE keeps in `PlayerTemplate`: the three sides
|
||||
@@ -62,7 +90,8 @@ on demand.
|
||||
### `ra3.map`
|
||||
Map discovery and loading: scans `MapsMultiplayer.big` for main map entries,
|
||||
unwraps the two compression layers (`BIG4` RefPack → `EAR\0` wrapper → RefPack →
|
||||
`CkMp`), and recovers `Player_N_Start` waypoint coordinates. Degenerate
|
||||
`CkMp`), recovers `Player_N_Start` waypoint coordinates, and decodes the
|
||||
localized display names from the install's `gamestrings.csf`. Degenerate
|
||||
extractions are rejected so the caller can fall back.
|
||||
|
||||
### `ra3.skirmish`
|
||||
@@ -72,14 +101,21 @@ passive + harvester income, a simple build AI, movement and combat on a fixed
|
||||
|
||||
### `ra3.render`
|
||||
A dependency-free software renderer: an ARGB8888 `image` framebuffer with
|
||||
blit/line/circle primitives, a TGA decoder for the game's map art, a 24-bit BMP
|
||||
encoder for headless output, and `compose` which overlays a world grid and
|
||||
markers (start positions, live units) onto the map art.
|
||||
blit/line/circle/text primitives (an embedded 8x8 bitmap font), a TGA decoder for
|
||||
the game's map art, a 24-bit BMP encoder for headless output, and `compose` which
|
||||
overlays a world grid and markers (start positions, live units) onto the map art.
|
||||
|
||||
### `ra3.ui`
|
||||
The windowed viewer. The SDL3 backend streams the rendered image to a texture
|
||||
with pan/zoom and Esc-to-quit; when the build has no SDL3, a null backend
|
||||
returns `false` so the caller writes an offscreen image instead.
|
||||
The SDL3 backend: `sdl_display` implements the `ra3.client::display` primitives
|
||||
using an `SDL_Renderer` streaming texture. Cheap and dependency-light, it is the
|
||||
fallback when Vulkan is unavailable. A null backend returns `false` so the build
|
||||
still runs without SDL3.
|
||||
|
||||
### `ra3.vulkan`
|
||||
The accelerated backend: `vulkan_display` implements the same primitives and
|
||||
adds `present_terrain`, a GPU heightfield raymarcher (mipmapped tile atlas with a
|
||||
replicated gutter and the retail SAGE blend ramp). A null backend reports failure
|
||||
when no Vulkan loader is present.
|
||||
|
||||
## Design rules
|
||||
|
||||
|
||||
Reference in New Issue
Block a user