Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
39d0c10
Load Maelstrom's data: schema converter plus its baked mesh and textu…
ivan-ushakov Aug 2, 2026
6536a62
Maelstrom UI: restore the pre-2008 background camera and minimap rota…
ivan-ushakov Aug 3, 2026
834391e
Maelstrom: put the global trigger chain where the engine looks for it
ivan-ushakov Aug 3, 2026
805102b
Maelstrom UI: read control show modes written flat, before they were …
ivan-ushakov Aug 3, 2026
bcff415
Maelstrom UI: restore control captions, border colours and depth
ivan-ushakov Aug 4, 2026
fdbf57c
Maelstrom: read the world's own lighting, written flat before 2008
ivan-ushakov Aug 4, 2026
98fdd3f
Maelstrom: select the pre-2008 schema at compile time, and read the s…
ivan-ushakov Aug 4, 2026
60e55b0
Maelstrom: read the preset group, which is still part of the world
ivan-ushakov Aug 4, 2026
57547b9
Sky cubemap: render it again, and let reflective materials read it
ivan-ushakov Aug 4, 2026
2956d9d
Maelstrom: take the model's own bound box, not the empty logic one
ivan-ushakov Aug 5, 2026
1e67532
Classify a texture's alpha again, as cD3DRender::CreateTexture did
ivan-ushakov Aug 5, 2026
5cb3b56
Maelstrom: restore the pre-2008 object lighting and shadow colour
ivan-ushakov Aug 5, 2026
0de63cb
Cull back faces in the 3dx renderer, as cD3DRender::setCamera does
ivan-ushakov Aug 5, 2026
15de48c
Environment: pick flock scale and wind from the float random range
ivan-ushakov Aug 7, 2026
3d64e46
Draw silhouetted units even though the outline is still unported
ivan-ushakov Aug 7, 2026
78c5986
Build model meshes again: test for a device, not for the D3D9 one
ivan-ushakov Aug 7, 2026
65d135f
Bound the per-object animation indices that only ever held zero
ivan-ushakov Aug 7, 2026
752d826
Maelstrom: read the animation chains, and fold the pre-2008 gait ids
ivan-ushakov Aug 7, 2026
16b6d81
Maelstrom: document how to lay out a run directory and run the converter
ivan-ushakov Aug 7, 2026
d1757f7
Maelstrom: bring the register up to date with the last two fixes
ivan-ushakov Aug 8, 2026
4eb2ad6
Maelstrom: read the model's real visibility groups out of the cache
ivan-ushakov Aug 8, 2026
43a8112
Maelstrom: record the physics dead ends, and how to avoid them
ivan-ushakov Aug 8, 2026
85a1288
Maelstrom: bank aircraft by the pre-2008 divisor, not the radian one
ivan-ushakov Aug 8, 2026
a95bddc
Drop an assert that could only ever fail, and register an 11th missin…
ivan-ushakov Aug 9, 2026
9e79f7c
Fail with the world's name when its data is missing, instead of segfa…
ivan-ushakov Aug 9, 2026
a271818
Maelstrom: renumber the indexed options against our own lists
ivan-ushakov Aug 9, 2026
0d8ea2f
Maelstrom: render its own bitmap fonts instead of substituting a True…
ivan-ushakov Aug 9, 2026
125942a
Maelstrom: read the camera's limits, which moved out of the environment
ivan-ushakov Aug 9, 2026
dad82d5
Maelstrom: sort the eleven unresolved classes, and port the three tha…
ivan-ushakov Aug 9, 2026
8b9c135
Copy the sky cubemap's faces on the frame's command buffer, not their…
ivan-ushakov Aug 9, 2026
7abd3c4
Reflect the sky cubemap when reflections are off, and load the wave maps
ivan-ushakov Aug 9, 2026
b9808da
Spell the case-insensitive compare the way MSVC does
ivan-ushakov Aug 9, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ The porting registers and format notes live in `Documents/`:
- [Documents/Sound-PORTING.md](Documents/Sound-PORTING.md) — audio: DirectSound out, miniaudio in.
- [Documents/Video-PORTING.md](Documents/Video-PORTING.md) — video: Bink and AVI, on ffmpeg.
- [Documents/InPlaceArchive.md](Documents/InPlaceArchive.md) — the InPlace archive format and the `.3dxG` model cache.
- [Documents/Maelstrom-PORTING.md](Documents/Maelstrom-PORTING.md) — running Maelstrom's data on this engine: the schema drift, the converter, and the cache formats its models and textures ship in.

## Current state

Expand Down
21 changes: 21 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -364,6 +364,27 @@ if(VISTA_ASAN)
message(STATUS "AddressSanitizer: ON (engine targets only; dependencies stay uninstrumented)")
endif()

# Which game's data this binary reads.
#
# Maelstrom (KD Lab, 2007) ships data written by a VistaEngine from before ~Aug 2007;
# this tree is a 2008+ snapshot. Most of the drift the archive absorbs on its own --
# XPrmIArchive skips names it does not know -- but where a field CHANGED NESTING or
# CHANGED OWNER there is nothing to skip: the reader asks for a block the old writer
# never wrote, and the whole subtree goes unread. Those sites cannot be served by one
# body of code without guessing at load time which schema is in front of them, so they
# are written twice and selected here.
#
# The rule at such a site is `#ifdef MAELSTROM_DATA` / `#else` / `#endif`, with the
# 2008 layout in the #else so a stock build is the code that was already there. Grep
# MAELSTROM_DATA for the full set; Documents/Maelstrom-PORTING.md explains each one.
#
# ON builds a Maelstrom binary, which cannot load Perimeter 2's data, and vice versa.
option(MAELSTROM_DATA "Read Maelstrom's (pre-2008) data schema instead of Perimeter 2's" OFF)
if(MAELSTROM_DATA)
add_compile_definitions(MAELSTROM_DATA)
message(STATUS "Data schema: Maelstrom (pre-2008)")
endif()

add_subdirectory(XLibs.Net)
add_subdirectory(Util)
add_subdirectory(AI)
Expand Down
1,134 changes: 1,134 additions & 0 deletions Documents/Maelstrom-PORTING.md

Large diffs are not rendered by default.

8 changes: 5 additions & 3 deletions Documents/Render-PORTING.md

Large diffs are not rendered by default.

26 changes: 26 additions & 0 deletions Environment/ActionsEnvironmental.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ REGISTER_CLASS(Action, ActionSetWaterColor, "Погода\\Установить
REGISTER_CLASS(Action, ActionSetReflectSkyColor, "Погода\\Установить цвет отражённого неба")
REGISTER_CLASS(Action, ActionSetTimeScale, "Погода\\Скорость течения времени суток на мире")
REGISTER_CLASS(Action, ActionSetWaterLevel, "Погода\\Установить уровень воды")
#ifdef MAELSTROM_DATA
REGISTER_CLASS(Action, ActionSetCoastSprites, "Погода\\Параметры прибрежных спрайтов")
#endif

REGISTER_CLASS(Action, ActionSetEffect, "Глобальные действия\\Включить/выключить эффект");

Expand Down Expand Up @@ -395,6 +398,29 @@ void ActionSetFogOfWar::activate()
}
}

#ifdef MAELSTROM_DATA
ActionSetCoastSprites::ActionSetCoastSprites()
{
// The trigger editor opened the action on the world's current settings and saved the
// difference, so the constructor has to start from them, not from an empty attribute set.
if(environment && environment->GetCoastSprites())
coastSprites_ = environment->GetCoastSprites()->attributes();
}

void ActionSetCoastSprites::serialize(Archive& ar)
{
__super::serialize(ar);
ar.serialize(coastSprites_, "coastSprites", "Прибрежные спрайты");
}

void ActionSetCoastSprites::activate()
{
if(environment)
if(cCoastSprites* coastSprites = environment->GetCoastSprites())
coastSprites->setAttributes(coastSprites_);
}
#endif

ActionSetWaterOpacity::ActionSetWaterOpacity()
{
if(environment){
Expand Down
23 changes: 23 additions & 0 deletions Environment/ActionsEnvironmental.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
#include "Physics/WindMap.h"
#include "Starforce.h"
#include "Units/LabelObject.h"
#ifdef MAELSTROM_DATA
#include "Environment/EnvironmentColors.h" // CoastSpritesAttributes, for ActionSetCoastSprites
#endif

struct ActionActivateSources : Action
{
Expand Down Expand Up @@ -209,6 +212,26 @@ class ActionSetSilhouette : public Action
void activate(){};
};

#ifdef MAELSTROM_DATA
// Maelstrom's own action, dropped by 2008 along with Environment's copy of the coast sprite
// attributes -- the sprites are still here and still read from the world, only nothing could
// change them again once the world was loaded. Every screen of the main menu sets its own
// (14 call sites in Scripts\Content\Triggers\MAIN MENU.scr, the "Waves*" trigger of each
// screen's environment block), so without it the shoreline keeps the menu world's opening
// settings through every screen.
class ActionSetCoastSprites : public Action
{
public:
ActionSetCoastSprites();

void serialize(Archive& ar);
void activate();

private:
CoastSpritesAttributes coastSprites_;
};
#endif

class ActionSetFogOfWar : public Action
{
public:
Expand Down
Loading
Loading