Replace the starinfo statefile with C++ maps.
This breaks all save file compatibility, but I don't care. Because of the dynamic nature of the end result I have in mind, there's no sane way to maintain save file compatibility. The group file code looks a bit more complex to untangle, so that will come in another commit. The way to save this information in the "pluggable module" form will be to just export large JSON tables of the masks.
This commit is contained in:
@@ -22,5 +22,6 @@ uqm_HFILES="battlecontrols.h battle.h build.h clock.h cnctdlg.h coderes.h
|
||||
starmap.h
|
||||
units.h uqmdebug.h util.h velocity.h weapon.h"
|
||||
uqm_CXXFILES="
|
||||
state-modern.cpp
|
||||
cxxlist.cpp
|
||||
"
|
||||
|
||||
@@ -1324,6 +1324,7 @@ InitSolarSys (void)
|
||||
LoadLanderData ();
|
||||
|
||||
Reentry = (GLOBAL (ShipFacing) != 0);
|
||||
fprintf( stderr, "Renetry to system is: %d\n", Reentry );
|
||||
if (!Reentry)
|
||||
{
|
||||
GLOBAL (autopilot.x) = ~0;
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
#include "state.h"
|
||||
|
||||
#include "uqm/starmap.h"
|
||||
#include "uqm/save.h"
|
||||
#include "uqm/planets/planets.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#include <iostream>
|
||||
|
||||
#include <string>
|
||||
#include <compare>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
|
||||
struct Coord
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
|
||||
std::strong_ordering operator <=> ( const Coord & ) const= default;
|
||||
};
|
||||
|
||||
struct WorldState
|
||||
{
|
||||
DWORD ScanRetrieveMask[NUM_SCAN_TYPES];
|
||||
};
|
||||
|
||||
struct WorldDescriptor
|
||||
{
|
||||
int planetNumber;
|
||||
int moonNumber; // -1 is world itself.
|
||||
|
||||
std::strong_ordering operator <=> ( const WorldDescriptor & ) const= default;
|
||||
};
|
||||
|
||||
using SolarSystemTable= std::map< WorldDescriptor, WorldState >;
|
||||
using GalaxyTable= std::map< Coord, SolarSystemTable >;
|
||||
|
||||
static auto &
|
||||
galaxy()
|
||||
{
|
||||
static GalaxyTable table;
|
||||
return table;
|
||||
}
|
||||
|
||||
static auto
|
||||
getCurrentCoord()
|
||||
{
|
||||
const auto &star= *CurStarDescPtr;
|
||||
const Coord pos{ .x{ star.star_pt.x }, .y{ star.star_pt.y } };
|
||||
return pos;
|
||||
}
|
||||
|
||||
static auto &
|
||||
getCurrentWorldMasks()
|
||||
{
|
||||
const Coord pos= getCurrentCoord();
|
||||
|
||||
const int planet_index = (pSolarSysState->pBaseDesc->pPrevDesc
|
||||
- pSolarSysState->PlanetDesc);
|
||||
const int moon_index= (pSolarSysState->pOrbitalDesc->pPrevDesc
|
||||
== pSolarSysState->SunDesc)
|
||||
? -1
|
||||
: (pSolarSysState->pOrbitalDesc
|
||||
- pSolarSysState->MoonDesc);
|
||||
|
||||
return galaxy()[ pos ][ { planet_index, moon_index } ].ScanRetrieveMask;
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void
|
||||
GetPlanetInfo()
|
||||
{
|
||||
static_assert( sizeof( getCurrentWorldMasks() ) == sizeof( WorldState ) );
|
||||
std::memcpy( pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask, getCurrentWorldMasks(), sizeof( getCurrentWorldMasks() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PutPlanetInfo()
|
||||
{
|
||||
static_assert( sizeof( getCurrentWorldMasks() ) == sizeof( WorldState ) );
|
||||
std::memcpy( getCurrentWorldMasks(), pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask, sizeof( getCurrentWorldMasks() ) );
|
||||
}
|
||||
|
||||
void
|
||||
InitPlanetInfo()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
UninitPlanetInfo()
|
||||
{
|
||||
galaxy().clear();
|
||||
}
|
||||
}
|
||||
+1
-149
@@ -43,7 +43,7 @@ struct GAME_STATE_FILE
|
||||
|
||||
static GAME_STATE_FILE state_files[NUM_STATE_FILES] =
|
||||
{
|
||||
{"STARINFO", STAR_BUFSIZE, STATE_FILE_ITRAILER},
|
||||
{"PLACEHOLDER", 0, STATE_FILE_ITRAILER},
|
||||
{"RANDGRPINFO", RAND_BUFSIZE, STATE_FILE_ITRAILER},
|
||||
{"DEFGRPINFO", DEF_BUFSIZE, STATE_FILE_ITRAILER}
|
||||
};
|
||||
@@ -204,151 +204,3 @@ SeekStateFile (GAME_STATE_FILE *fp, long offset, int whence)
|
||||
fp->ptr = offset;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InitPlanetInfo (void)
|
||||
{
|
||||
GAME_STATE_FILE *fp;
|
||||
|
||||
fp = OpenStateFile (STARINFO_FILE, "wb");
|
||||
if (fp)
|
||||
{
|
||||
STAR_DESC *pSD;
|
||||
|
||||
// Set record offsets for all stars to 0 (not present)
|
||||
pSD = &star_array[0];
|
||||
do
|
||||
{
|
||||
swrite_32 (fp, 0);
|
||||
++pSD;
|
||||
} while (pSD->star_pt.x <= MAX_X_UNIVERSE
|
||||
&& pSD->star_pt.y <= MAX_Y_UNIVERSE);
|
||||
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UninitPlanetInfo (void)
|
||||
{
|
||||
DeleteStateFile (STARINFO_FILE);
|
||||
}
|
||||
|
||||
#define OFFSET_SIZE (sizeof (DWORD))
|
||||
#define SCAN_RECORD_SIZE (sizeof (DWORD) * NUM_SCAN_TYPES)
|
||||
|
||||
void
|
||||
GetPlanetInfo (void)
|
||||
{
|
||||
GAME_STATE_FILE *fp;
|
||||
|
||||
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[BIOLOGICAL_SCAN] = 0;
|
||||
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[MINERAL_SCAN] = 0;
|
||||
pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask[ENERGY_SCAN] = 0;
|
||||
|
||||
fp = OpenStateFile (STARINFO_FILE, "rb");
|
||||
if (fp)
|
||||
{
|
||||
COUNT star_index, planet_index, moon_index;
|
||||
DWORD offset;
|
||||
|
||||
star_index = (COUNT)(CurStarDescPtr - star_array);
|
||||
planet_index = (COUNT)(pSolarSysState->pBaseDesc->pPrevDesc
|
||||
- pSolarSysState->PlanetDesc);
|
||||
if (pSolarSysState->pOrbitalDesc->pPrevDesc == pSolarSysState->SunDesc)
|
||||
moon_index = 0;
|
||||
else
|
||||
moon_index = (COUNT)(pSolarSysState->pOrbitalDesc
|
||||
- pSolarSysState->MoonDesc + 1);
|
||||
|
||||
SeekStateFile (fp, star_index * OFFSET_SIZE, SEEK_SET);
|
||||
sread_32 (fp, &offset);
|
||||
|
||||
if (offset)
|
||||
{
|
||||
COUNT i;
|
||||
|
||||
// Skip scan records for all preceeding planets to the one we need
|
||||
for (i = 0; i < planet_index; ++i)
|
||||
offset += (pSolarSysState->PlanetDesc[i].NumPlanets + 1) *
|
||||
SCAN_RECORD_SIZE;
|
||||
|
||||
// Skip scan records for all preceeding moons to the one we need
|
||||
offset += moon_index * SCAN_RECORD_SIZE;
|
||||
|
||||
SeekStateFile (fp, offset, SEEK_SET);
|
||||
sread_a32 (fp, pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask,
|
||||
NUM_SCAN_TYPES);
|
||||
}
|
||||
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
PutPlanetInfo (void)
|
||||
{
|
||||
GAME_STATE_FILE *fp;
|
||||
|
||||
fp = OpenStateFile (STARINFO_FILE, "r+b");
|
||||
if (fp)
|
||||
{
|
||||
COUNT i;
|
||||
COUNT star_index, planet_index, moon_index;
|
||||
DWORD offset;
|
||||
|
||||
star_index = (COUNT)(CurStarDescPtr - star_array);
|
||||
planet_index = (COUNT)(pSolarSysState->pBaseDesc->pPrevDesc
|
||||
- pSolarSysState->PlanetDesc);
|
||||
if (pSolarSysState->pOrbitalDesc->pPrevDesc == pSolarSysState->SunDesc)
|
||||
moon_index = 0;
|
||||
else
|
||||
moon_index = (COUNT)(pSolarSysState->pOrbitalDesc
|
||||
- pSolarSysState->MoonDesc + 1);
|
||||
|
||||
SeekStateFile (fp, star_index * OFFSET_SIZE, SEEK_SET);
|
||||
sread_32 (fp, &offset);
|
||||
|
||||
if (offset == 0)
|
||||
{ // Scan record not present yet -- init it
|
||||
DWORD ScanRetrieveMask[NUM_SCAN_TYPES] =
|
||||
{
|
||||
0, 0, 0,
|
||||
};
|
||||
|
||||
offset = LengthStateFile (fp);
|
||||
|
||||
// Write the record offset
|
||||
SeekStateFile (fp, star_index * OFFSET_SIZE, SEEK_SET);
|
||||
swrite_32 (fp, offset);
|
||||
|
||||
// Init scan records for all planets and moons in the system
|
||||
SeekStateFile (fp, offset, SEEK_SET);
|
||||
for (i = 0; i < pSolarSysState->SunDesc[0].NumPlanets; ++i)
|
||||
{
|
||||
COUNT j;
|
||||
|
||||
swrite_a32 (fp, ScanRetrieveMask, NUM_SCAN_TYPES);
|
||||
// init moons
|
||||
for (j = 0; j < pSolarSysState->PlanetDesc[i].NumPlanets; ++j)
|
||||
swrite_a32 (fp, ScanRetrieveMask, NUM_SCAN_TYPES);
|
||||
}
|
||||
}
|
||||
|
||||
// Skip scan records for all preceeding planets to the one we need
|
||||
for (i = 0; i < planet_index; ++i)
|
||||
offset += (pSolarSysState->PlanetDesc[i].NumPlanets + 1) *
|
||||
SCAN_RECORD_SIZE;
|
||||
|
||||
// Skip scan records for all preceeding moons to the one we need
|
||||
offset += moon_index * SCAN_RECORD_SIZE;
|
||||
|
||||
SeekStateFile (fp, offset, SEEK_SET);
|
||||
swrite_a32 (fp, pSolarSysState->SysInfo.PlanetInfo.ScanRetrieveMask,
|
||||
NUM_SCAN_TYPES);
|
||||
|
||||
CloseStateFile (fp);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-9
@@ -52,16 +52,9 @@ extern void BuildGroups (void);
|
||||
|
||||
typedef struct GAME_STATE_FILE GAME_STATE_FILE;
|
||||
|
||||
// This is still preserved, to let `save.c` and `load.c` still compile.
|
||||
#define STARINFO_FILE 0
|
||||
//"starinfo.dat"
|
||||
// Hack for up to 4k star systems (for now)...
|
||||
// Each system having up to 15 planets with
|
||||
// up to 5 moons each. This is somewhat
|
||||
// overkill.... but I don't want to unspool
|
||||
// all of the C arrays just yet. Memory
|
||||
// is cheap, so let it get big...
|
||||
#define STAR_BUFSIZE (4096 * sizeof (DWORD) \
|
||||
+ 16 * 5 * 4096 * (3 * sizeof (DWORD)))
|
||||
|
||||
#define RANDGRPINFO_FILE 1
|
||||
//"randgrp.dat"
|
||||
#define RAND_BUFSIZE (4 * 1024)
|
||||
|
||||
Reference in New Issue
Block a user