This is the baseline for allowing for C++ generation.
Now to hook it all up...
This commit is contained in:
@@ -51,11 +51,14 @@ extern GenerateFunctions generateYehatFunctions;
|
||||
extern GenerateFunctions generateZoqFotPikFunctions;
|
||||
extern GenerateFunctions generateZoqFotPikScoutFunctions;
|
||||
|
||||
extern GenerateFunctions *getGenerateCxxFunctions( void );
|
||||
|
||||
|
||||
const GenerateFunctions *
|
||||
getGenerateFunctions (BYTE Index)
|
||||
getGenerateFunctions (STAR_DESC *const star, void **sup )
|
||||
{
|
||||
switch (Index)
|
||||
*sup= 0;
|
||||
switch (star->Index)
|
||||
{
|
||||
case SOL_DEFINED:
|
||||
return &generateSolFunctions;
|
||||
@@ -132,6 +135,10 @@ getGenerateFunctions (BYTE Index)
|
||||
return &generateIlwrathFunctions;
|
||||
default:
|
||||
return &generateDefaultFunctions;
|
||||
|
||||
case CXX_DEFINED:
|
||||
*sup= star->supplement;
|
||||
return getGenerateCxxFunctions();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
const GenerateFunctions *getGenerateFunctions (BYTE Index);
|
||||
const GenerateFunctions *getGenerateFunctions (STAR_DESC *star, void **sup);
|
||||
|
||||
enum
|
||||
{
|
||||
@@ -60,7 +60,7 @@ enum
|
||||
ANDROSYNTH_DEFINED,
|
||||
MYCON_TRAP_DEFINED,
|
||||
|
||||
CUSTOM_DEFINED,
|
||||
CXX_DEFINED,
|
||||
};
|
||||
|
||||
#define UMGAH_DEFINED TALKING_PET_DEFINED
|
||||
|
||||
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "uqm/planets/generate.h"
|
||||
|
||||
/*
|
||||
* XXX: Note that the way that defaults get called via C++ is a bit
|
||||
* indirect and wonky. The genFunc C table calls into the C++
|
||||
* wrappers which then call into the C++ object's vtable to these
|
||||
* functions here... which then call back out to the C functions
|
||||
* that would have been in the table. This does mean a bit more
|
||||
* pointer chasing on each call... But I'm not really worried.
|
||||
*
|
||||
* Performance concerns aren't an issue as far as I'm concerned;
|
||||
* after all -- Star Control 2 was a game that ran amazingly well
|
||||
* on a 486 or Pentium. I played it just fine on a 90 MHz Pentium
|
||||
* 1 with 32MiB of RAM (probably overkill on the RAM). My point
|
||||
* is that a second layer of indirection and cache misses won't
|
||||
* even be noticed, given how little this game should tax a
|
||||
* modern CPU.
|
||||
*
|
||||
* As these functions are used to build a solar system, I think
|
||||
* it only affects the "load time" for these systems -- and
|
||||
* they're pretty easily loaded to begin with. And all of
|
||||
* this indirection can go away once the planet handling at
|
||||
* a higher level becomes C++ -- it can just call the vptrs
|
||||
* directly.
|
||||
*
|
||||
*
|
||||
* =====================================================================
|
||||
*
|
||||
* Right now I need a lot of glue C++ to keep things all together,
|
||||
* but once I can start to move more of the core program over
|
||||
* to C++; I'll be able to let this glue fall away. This code is
|
||||
* an example of that kind of glue.
|
||||
*/
|
||||
|
||||
namespace Planets ::detail:: Generate
|
||||
{
|
||||
Generator::~Generator()= default;
|
||||
|
||||
|
||||
// All of the default C++ generator functions forward to the
|
||||
// plain C default impls. The idea is that you derive your
|
||||
// special generator from the C++ one, just filling in the
|
||||
// details you need. It _should_, in practice, clean up
|
||||
// the boilerplate in the various `generate/genXXX` files.
|
||||
//
|
||||
// The `GenerateBindToCXX_XYZ` functions just forward to
|
||||
// the C++ generator parameter in question. I still have
|
||||
// to figure out where to store/parameterize that generator
|
||||
// object.
|
||||
//
|
||||
// I think I'll just add an extra parameter to the function.
|
||||
//
|
||||
// That parameter will be a function pointer that returns
|
||||
// a pointer to `Planets::detail::Generate::exports::Generator`
|
||||
// in question.
|
||||
|
||||
DefaultGenerator::~DefaultGenerator()= default;
|
||||
|
||||
void
|
||||
DefaultGenerator::initNpcs( SolarSystem *const solarSys )
|
||||
{
|
||||
// This always returns true...
|
||||
std::ignore= GenerateDefault_initNpcs( solarSys );
|
||||
}
|
||||
|
||||
void
|
||||
DefaultGenerator::reinitNpcs( SolarSystem *const solarSys )
|
||||
{
|
||||
// This always returns true...
|
||||
std::ignore= GenerateDefault_reinitNpcs( solarSys );
|
||||
}
|
||||
|
||||
void
|
||||
DefaultGenerator::uninitNpcs( SolarSystem *const solarSys )
|
||||
{
|
||||
// This always returns true...
|
||||
std::ignore= GenerateDefault_uninitNpcs( solarSys );
|
||||
}
|
||||
|
||||
bool
|
||||
DefaultGenerator::generatePlanets( SolarSystem *const solarSys )
|
||||
{
|
||||
return GenerateDefault_generatePlanets( solarSys );
|
||||
}
|
||||
|
||||
bool
|
||||
DefaultGenerator::generateMoons( SolarSystem *const solarSys, PLANET_DESC *const planet )
|
||||
{
|
||||
return GenerateDefault_generateMoons( solarSys, planet );
|
||||
}
|
||||
|
||||
bool
|
||||
DefaultGenerator::generateOrbital( SolarSystem *const solarSys, PLANET_DESC *const world )
|
||||
{
|
||||
return GenerateDefault_generateOrbital( solarSys, world );
|
||||
}
|
||||
|
||||
bool
|
||||
DefaultGenerator::generateName( SolarSystem *const solarSys, PLANET_DESC *const world )
|
||||
{
|
||||
return GenerateDefault_generateName( solarSys, world );
|
||||
}
|
||||
|
||||
|
||||
COUNT
|
||||
DefaultGenerator::generateMinerals( SolarSystem *const solarSys, PLANET_DESC *const world,
|
||||
const COUNT whichNode, NODE_INFO *const info )
|
||||
{
|
||||
return GenerateDefault_generateMinerals( solarSys, world, whichNode, info );
|
||||
}
|
||||
|
||||
|
||||
COUNT
|
||||
DefaultGenerator::generateEnergy( SolarSystem *const solarSys, PLANET_DESC *const world,
|
||||
const COUNT whichNode, NODE_INFO *const info )
|
||||
{
|
||||
return GenerateDefault_generateEnergy( solarSys, world, whichNode, info );
|
||||
}
|
||||
|
||||
|
||||
COUNT
|
||||
DefaultGenerator::generateLife( SolarSystem *const solarSys, PLANET_DESC *const world,
|
||||
const COUNT whichNode, NODE_INFO *const info )
|
||||
{
|
||||
return GenerateDefault_generateLife( solarSys, world, whichNode, info );
|
||||
}
|
||||
|
||||
bool
|
||||
DefaultGenerator::pickupMinerals( SolarSystem *const solarSys, PLANET_DESC *const world,
|
||||
const COUNT whichNode )
|
||||
{
|
||||
return GenerateDefault_pickupMinerals( solarSys, world, whichNode );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DefaultGenerator::pickupEnergy( SolarSystem *const solarSys, PLANET_DESC *const world,
|
||||
const COUNT whichNode )
|
||||
{
|
||||
return GenerateDefault_pickupEnergy( solarSys, world, whichNode );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DefaultGenerator::pickupLife( SolarSystem *const solarSys, PLANET_DESC *const world,
|
||||
const COUNT whichNode )
|
||||
{
|
||||
return GenerateDefault_pickupLife( solarSys, world, whichNode );
|
||||
}
|
||||
}
|
||||
@@ -113,6 +113,91 @@ struct GenerateFunctions {
|
||||
};
|
||||
|
||||
#if defined(__cplusplus)
|
||||
} // extern "C"
|
||||
|
||||
namespace Planets ::detail:: Generate_m
|
||||
{
|
||||
inline namespace exports
|
||||
{
|
||||
class Generator;
|
||||
class DefaultGenerator;
|
||||
|
||||
using SolarSystem= SOLARSYS_STATE;
|
||||
}
|
||||
|
||||
class exports::Generator
|
||||
{
|
||||
public:
|
||||
virtual ~Generator()= 0;
|
||||
|
||||
virtual void initNpcs( SolarSystem *solarSys )= 0;
|
||||
virtual void reinitNpcs( SolarSystem *solarSys )= 0;
|
||||
virtual void uninitNpcs( SolarSystem *solarSys )= 0;
|
||||
virtual bool generatePlanets( SolarSystem *solarSys )= 0;
|
||||
virtual bool generateMoons( SolarSystem *solarSys,
|
||||
PLANET_DESC *planet )= 0;
|
||||
virtual bool generateOrbital( SolarSystem *solarSys,
|
||||
PLANET_DESC *world)= 0;
|
||||
virtual bool generateName( const SolarSystem *,
|
||||
const PLANET_DESC *world)= 0;
|
||||
// The following functions return the number of objects being generated
|
||||
// (or the index of the current object in some cases)
|
||||
virtual COUNT generateMinerals( const SolarSystem *,
|
||||
const PLANET_DESC *world, COUNT whichNode, NODE_INFO * )= 0;
|
||||
virtual COUNT generateEnergy( const SolarSystem *,
|
||||
const PLANET_DESC *world, COUNT whichNode, NODE_INFO * )= 0;
|
||||
virtual COUNT generateLife( const SolarSystem *,
|
||||
const PLANET_DESC *world, COUNT whichNode, NODE_INFO * )= 0;
|
||||
// The following functions return true if the node should be removed
|
||||
// from the surface, i.e. picked up.
|
||||
virtual bool pickupMinerals( SolarSystem *solarSys,
|
||||
PLANET_DESC *world, COUNT whichNode )= 0;
|
||||
virtual bool pickupEnergy( SolarSystem *solarSys,
|
||||
PLANET_DESC *world, COUNT whichNode )= 0;
|
||||
virtual bool pickupLife( SolarSystem *solarSys,
|
||||
PLANET_DESC *world, COUNT whichNode )= 0;
|
||||
};
|
||||
|
||||
class exports::DefaultGenerator
|
||||
: virtual public Generator
|
||||
{
|
||||
public:
|
||||
~DefaultGenerator() override;
|
||||
|
||||
void initNpcs(SolarSystem *solarSys) override;
|
||||
void reinitNpcs(SolarSystem *solarSys) override;
|
||||
void uninitNpcs(SolarSystem *solarSys) override;
|
||||
bool generatePlanets(SolarSystem *solarSys) override;
|
||||
bool generateMoons(SolarSystem *solarSys,
|
||||
PLANET_DESC *planet) override;
|
||||
bool generateOrbital(SolarSystem *solarSys,
|
||||
PLANET_DESC *world) override;
|
||||
bool generateName(const SolarSystem *,
|
||||
const PLANET_DESC *world) override;
|
||||
|
||||
// The following functions return the number of objects being generated
|
||||
// (or the index of the current object in some cases)
|
||||
COUNT generateMinerals(const SolarSystem *,
|
||||
const PLANET_DESC *world, COUNT whichNode, NODE_INFO *) override;
|
||||
COUNT generateEnergy(const SolarSystem *,
|
||||
const PLANET_DESC *world, COUNT whichNode, NODE_INFO *) override;
|
||||
COUNT generateLife(const SolarSystem *,
|
||||
const PLANET_DESC *world, COUNT whichNode, NODE_INFO *) override;
|
||||
|
||||
// The following functions return true if the node should be removed
|
||||
// from the surface, i.e. picked up.
|
||||
bool pickupMinerals(SolarSystem *solarSys,
|
||||
PLANET_DESC *world, COUNT whichNode) override;
|
||||
bool pickupEnergy(SolarSystem *solarSys,
|
||||
PLANET_DESC *world, COUNT whichNode) override;
|
||||
bool pickupLife(SolarSystem *solarSys,
|
||||
PLANET_DESC *world, COUNT whichNode) override;
|
||||
};
|
||||
}
|
||||
|
||||
namespace Planets::inline exports::inline Generate_m
|
||||
{
|
||||
using namespace detail::Generate_m::exports;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -4,3 +4,4 @@ uqm_CFILES="gendefault.c genand.c genburv.c genchmmr.c gencol.c gendru.c
|
||||
genthrad.c gentrap.c genutw.c genvault.c genvux.c genwreck.c
|
||||
genyeh.c genzfpscout.c genzoq.c"
|
||||
uqm_HFILES="genall.h gendefault.h"
|
||||
uqm_CXXFILES="cxx-generator.cpp"
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include "genall.h"
|
||||
#include "../planets.h"
|
||||
#include "../lander.h"
|
||||
#include "../../encount.h"
|
||||
#include "../../gamestr.h"
|
||||
#include "../../globdata.h"
|
||||
#include "../../grpinfo.h"
|
||||
#include "../../races.h"
|
||||
#include "../../state.h"
|
||||
#include "../../sounds.h"
|
||||
#include "libs/mathlib.h"
|
||||
|
||||
|
||||
/*
|
||||
* These bindings allow for the legacy C code to call into "GenerateFunctions" objects
|
||||
* and have those calls mapped into the C++ virtual table driven object which handles
|
||||
* the actual generation.
|
||||
*
|
||||
* This permits me to slowly migrate over the legacy C generators into C++. And to
|
||||
* mess around with new C++-only generators.
|
||||
*
|
||||
* One nice advantage of this is that any C++ generator can inherit from another to
|
||||
* specialize it. This permits `Default`ed forms to just use the base C++ defaulting
|
||||
* class, using normal C++ `override` semantics.
|
||||
*
|
||||
*
|
||||
* =====================================================================
|
||||
*
|
||||
* Right now I need a lot of glue C++ to keep things all together,
|
||||
* but once I can start to move more of the core program over
|
||||
* to C++; I'll be able to let this glue fall away. This code is
|
||||
* an example of that kind of glue.
|
||||
*/
|
||||
|
||||
namespace Planets ::detail:: CxxGeneratorBindings_m
|
||||
{
|
||||
namespace
|
||||
{
|
||||
auto &
|
||||
getGenerator( const SolarSystem *const solarSys )
|
||||
{
|
||||
return *static_cast< Generator * >( solarSys->genSupplement );
|
||||
}
|
||||
|
||||
bool
|
||||
initNpcs( SolarSystem *const solarSys )
|
||||
{
|
||||
getGenerator( solarSys ).initNpcs( solarSys );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
reinitNpcs( SolarSystem *const solarSys )
|
||||
{
|
||||
getGenerator( solarSys ).reinitNpcs( solarSys );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
uninitNpcs( SolarSystem *const solarSys )
|
||||
{
|
||||
getGenerator( solarSys ).uninitNpcs( solarSys );
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
generatePlanets( SolarSystem *const solarSys )
|
||||
{
|
||||
return getGenerator( solarSys ).generatePlanets( solarSys );
|
||||
}
|
||||
|
||||
bool
|
||||
generateMoons( SolarSystem *const solarSys, PLANET_DESC *const planet )
|
||||
{
|
||||
return getGenerator( solarSys ).generateMoons( solarSys, planet );
|
||||
}
|
||||
|
||||
bool
|
||||
generateName( const SolarSystem *const solarSys, const PLANET_DESC *const world )
|
||||
{
|
||||
return getGenerator( solarSys ).generateName( solarSys, world );
|
||||
}
|
||||
|
||||
bool
|
||||
generateOrbital( SolarSystem *const solarSys, PLANET_DESC *const world )
|
||||
{
|
||||
return getGenerator( solarSys ).generateOrbital( solarSys, world );
|
||||
}
|
||||
|
||||
COUNT
|
||||
generateMinerals( const SolarSystem *const solarSys,
|
||||
const PLANET_DESC *const world, const COUNT whichNode, NODE_INFO *const info )
|
||||
{
|
||||
return getGenerator( solarSys ).generateMinerals( solarSys, world, whichNode, info );
|
||||
}
|
||||
|
||||
bool
|
||||
pickupMinerals( SolarSystem *const solarSys, PLANET_DESC *const world,
|
||||
const COUNT whichNode )
|
||||
{
|
||||
return getGenerator( solarSys ).pickupMinerals( solarSys, world, whichNode );
|
||||
}
|
||||
|
||||
COUNT
|
||||
generateEnergy( const SolarSystem *const solarSys,
|
||||
const PLANET_DESC *const world, const COUNT whichNode,
|
||||
NODE_INFO *const info )
|
||||
{
|
||||
return getGenerator( solarSys ).generateEnergy( solarSys, world, whichNode, info );
|
||||
}
|
||||
|
||||
bool
|
||||
pickupEnergy( SolarSystem *const solarSys, PLANET_DESC *const world,
|
||||
const COUNT whichNode )
|
||||
{
|
||||
return getGenerator( solarSys ).pickupEnergy( solarSys, world, whichNode );
|
||||
}
|
||||
|
||||
COUNT
|
||||
generateLife( const SolarSystem *const solarSys,
|
||||
const PLANET_DESC *const world, const COUNT whichNode, NODE_INFO *const info )
|
||||
{
|
||||
return getGenerator( solarSys ).generateLife( solarSys, world, whichNode, info );
|
||||
}
|
||||
|
||||
bool
|
||||
pickupLife( SolarSystem *const solarSys, PLANET_DESC *const world,
|
||||
const COUNT whichNode )
|
||||
{
|
||||
return getGenerator( solarSys ).pickupLife( solarSys, world, whichNode );
|
||||
}
|
||||
|
||||
const GenerateFunctions funcs = {
|
||||
/* .initNpcs = */ initNpcs,
|
||||
/* .reinitNpcs = */ reinitNpcs,
|
||||
/* .uninitNpcs = */ uninitNpcs,
|
||||
/* .generatePlanets = */ generatePlanets,
|
||||
/* .generateMoons = */ generateMoons,
|
||||
/* .generateName = */ generateName,
|
||||
/* .generateOrbital = */ generateOrbital,
|
||||
/* .generateMinerals = */ generateMinerals,
|
||||
/* .generateEnergy = */ generateEnergy,
|
||||
/* .generateLife = */ generateLife,
|
||||
/* .pickupMinerals = */ pickupMinerals,
|
||||
/* .pickupEnergy = */ pickupEnergy,
|
||||
/* .pickupLife = */ pickupLife,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
const GenerateFunctions *getGenerateCxxFunctions( void )
|
||||
{
|
||||
return &Planets::detail:: CxxGeneratorBindings_m::funcs;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef GENDEFAULT_H
|
||||
#define GENDEFAULT_H
|
||||
|
||||
#include "types.h"
|
||||
#include "../planets.h"
|
||||
#include "libs/compiler.h"
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
extern const GenerateFunctions *getGenerateCxxFunctions();
|
||||
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GENDEFAULT_H */
|
||||
|
||||
@@ -130,6 +130,8 @@ struct star_desc
|
||||
BYTE Index;
|
||||
BYTE Prefix;
|
||||
BYTE Postfix;
|
||||
|
||||
void *supplement; // The CXX builder's pointer gets put here.
|
||||
};
|
||||
|
||||
struct node_info
|
||||
@@ -249,6 +251,13 @@ struct solarsys_state
|
||||
BOOLEAN InOrbit;
|
||||
// Set to TRUE when player hits a world in an inner system
|
||||
// Homeworld encounters count as 'in orbit'
|
||||
|
||||
// This points to the actual C++ generator type, for C++
|
||||
// implemented generators.
|
||||
//
|
||||
// Since everything else probably ignores it... we can probably
|
||||
// avoid setting it to `nullptr`, for now...
|
||||
void *genSupplement;
|
||||
};
|
||||
|
||||
extern SOLARSYS_STATE *pSolarSysState;
|
||||
|
||||
@@ -1735,7 +1735,7 @@ ExploreSolarSys (void)
|
||||
|
||||
memset (pSolarSysState, 0, sizeof (*pSolarSysState));
|
||||
|
||||
SolarSysState.genFuncs = getGenerateFunctions (CurStarDescPtr->Index);
|
||||
SolarSysState.genFuncs = getGenerateFunctions (CurStarDescPtr, &SolarSysState.genSupplement);
|
||||
|
||||
InitSolarSys ();
|
||||
SetMenuSounds (MENU_SOUND_NONE, MENU_SOUND_NONE);
|
||||
|
||||
@@ -645,7 +645,7 @@ starRecurse (STAR_DESC *star, void *arg)
|
||||
SolarSysState.SunDesc[0].location.x = 0;
|
||||
SolarSysState.SunDesc[0].location.y = 0;
|
||||
//SolarSysState.SunDesc[0].radius = MIN_ZOOM_RADIUS;
|
||||
SolarSysState.genFuncs = getGenerateFunctions (star->Index);
|
||||
SolarSysState.genFuncs = getGenerateFunctions (star, &SolarSysState.genSupplement);
|
||||
|
||||
pSolarSysState = &SolarSysState;
|
||||
(*SolarSysState.genFuncs->generatePlanets) (&SolarSysState);
|
||||
|
||||
Reference in New Issue
Block a user