UFO: Alien Invasion
Loading...
Searching...
No Matches
sv_rma.cpp File Reference

Random map assembly code More info on map-assembly can be found at: http://ufoai.org/wiki/index.php/Mapping/Random_map_assembly. More...

#include "server.h"
#include "sv_rma.h"
#include "../shared/parse.h"
#include "../shared/thread.h"
Include dependency graph for sv_rma.cpp:

Go to the source code of this file.

Data Structures

class  Tile
 Stores the parsed data for a map tile. (See *.ump files). More...
class  TileSet
 A list of tiles with the same size and neighbouring requirements to randomly pick from. More...
class  Assembly
 Stores the parsed data of an assembly definition. See *.ump files. More...
struct  mToPlace_t
 Defines a tile to place. More...
struct  mPlaced_t
 Defines a placed tile. More...
class  MapInfo

Macros

#define ASSEMBLE_THREADS   2
#define PRINT_RMA_PROGRESS   0
 print some debugging info
#define SORT_BY_SIZE   1
 place the biggest 'required' tiles first. Helps oriental a lot, but is bad for village.
#define RMA2_MAX_REC   64
 max # of recursions
#define RMA2_MAX_TILEPOS   1700
 max # of valid tile/position combinations
#define TCM   50
 tile code multiplier. For the various debug printfs we want a number that we can easily divide through (20, 50, 100,...)
#define GAPS   25
 the # of different tiles we can store for a gap
#define MAX_RANDOM_MAP_WIDTH   32
#define MAX_RANDOM_MAP_HEIGHT   32
#define MAX_MAPASSEMBLIES   32
#define MAX_TILETYPES   128
#define MAX_TILESETS   16
#define MAX_TILESETTILES   16
#define MAX_TILESIZE   16
#define MAX_FIXEDTILES   64
#define MAX_ASSEMBLY_SEEDS   32
#define ALL_TILES   (0xfffffffeUL)
#define IS_SOLID(x)
#define ACW   6 /* ascii cell width */
#define ACH   3 /* ascii cell height */
#define MMW   13 /* map max width 13 means we support 12 */
#define MMH   13 /* map max height */

Functions

static void RandomList (const int n, short *list)
 Fills a list with random values between 0 and n.
static unsigned long tileMask (const char chr)
 Convert to tile spec - normalize the characters.
static void SV_TileMaskToString (unsigned long m, char *str)
static void SV_RmaPrintMap (const MapInfo *map)
static const TileSetSV_GetMapTileSet (const MapInfo *map, const char *tileSetName)
static const TileSV_GetMapTile (const MapInfo *map, const char *tileName)
static bool SV_ParseMapTileSet (const char *filename, const char **text, MapInfo *map, bool inherit)
 Parsed a tileset definition out of the ump-files.
static bool SV_ParseMapTile (const char *filename, const char **text, MapInfo *map, bool inherit)
 Parsed a tile definition out of the ump-files.
static const char * SV_GetCvarToken (const MapInfo *map, const Assembly *a, const char *token, const char *filename, const char **text, const char *errhead)
 Tries to extract a tile name from a cvar - the cvar value must start with a '+'.
static const char * SV_GetTileFromTileSet (const MapInfo *map, const char *filename, const char **text, const Assembly *a)
static bool SV_ParseAssemblySeeds (MapInfo *map, const char *filename, const char **text, Assembly *a)
 Parses a list of working seeds to assemble this rma assembly.
static void SV_GetTilesFromTileSet (const MapInfo *map, const char *filename, const char **text, Assembly *a)
static bool SV_ParseAssembly (MapInfo *map, const char *filename, const char **text, Assembly *a)
 Parses an assembly block.
static void SV_CombineAlternatives (unsigned long *mapAlts, const unsigned long tileAlts)
 Combines the alternatives/connection info of a map with a tile and sets the rating.
static void SV_ClearMap (MapInfo *map)
 Reset the map to empty state.
static bool SV_FitTile (const MapInfo *map, const Tile *tile, const int x, const int y)
 Checks if a given map-tile fits into the empty space (in a given location) of a map.
static bool SV_TestFilled (const MapInfo *map)
 Checks if the map is completely filled.
static void SV_DumpPlaced (const MapInfo *map, int pl)
 Debug function to dump the map location of a placed tile.
static void SV_AddTile (MapInfo *map, const Tile *tile, int x, int y, int idx, int pos)
 Adds a new map-tile to an assembled map. Also adds the tile to the placed-tiles list.
static void SV_RemoveTile (MapInfo *map, int *idx, int *pos)
 Rebuilds a assembled map up to the previous tile.
static void SV_BuildMapStrings (const MapInfo *map, char *asmTiles, char *asmPos, bool print)
 Creates the mapstrings as known from the ufoconsole.log and optionally prints them. This can also be used to dump the progress of the RMA process.
static unsigned long SV_GapGetFlagsAtAbsPos (MapInfo *map, int tileCode, int mapW, int mapX, int mapY)
 get the specs of a tile at map-x/y if it was placed where tileCode indicates
static bool SV_AddMissingTiles_r (MapInfo *map, int rec, int posListCnt, short myPosList[], const Tile *prevTile, int prevX, int prevY)
static bool SV_GapListBuild (MapInfo *map, int tilePosListCnt)
 Builds a list of map positions (gaps) and the tiles that can cover them.
static bool SV_GapCheckNeighbour (MapInfo *map, int tc1, int mapW, int mapH, int nx, int ny)
 Find a tile that meets the requirements of tc1 at a given pos.
static int SV_GapListReduce (MapInfo *map)
 Tries to find tiles that exclude all of their neighbours This is called only once, before recursion starts. So we can safely (ab)use the posTileList space for recursion 1.
static bool SV_AddMissingTiles (MapInfo *map)
 Tries to fill the missing tiles of the current map. While the 2010 algo used a 'by chance'-algo, this algo does a full tree search. Example: After placing the fixed and required tiles on a 8x8 map, we have say 32 places not yet covered by tiles. If there are 10 different tiles for each gap, we can have up to have 10^32 constellations to try. That's about one fantastillion. Impossible. Fortunately, there are usually many solutions to this puzzle. And we only need to find one working solution. But on some maps eg. 'forest large' with it's little brook, there are fewer solutions, so the search can take longer. In order to complete the search in a reasonable time, this algo uses several strategies:
static bool SV_AddMapTiles (MapInfo *map)
 Tries to build the map There are 3 categories of tiles:
static void SV_PrepareTilesToPlace (MapInfo *map)
 Prepare the list of tiles to place.
static int SV_AssemblyThread (void *data)
 The main function for the threads that try to create random map assemblies in parallel.
static int SV_ParallelSearch (MapInfo *map)
 Spawn ASSEMBLE_THREADS threads to try and assemble a map. The first map complete gets returned. Allocates a new copy of the map for each thread, and frees it at the end. Uses a timeout (initially 5 seconds). If the spawned threads have not completed by the timeout, they are restarted, with double the timeout.
static void SV_ParseUMP (const char *name, char *entityString, MapInfo *map, bool inherit)
 Parses an ump file that contains the random map definition.
static int cmpTileAreaSize (const void *a, const void *b)
static MapInfoSV_DoMapAssemble (MapInfo *map, const char *assembly, char *asmTiles, char *asmPos, const unsigned int seed, bool print)
static MapInfoSV_AssembleMap_ (const char *mapTheme, const char *assembly, char *asmTiles, char *asmPos, char *entityString, const unsigned int seed, bool print)
 Assembles a "random" map and parses the *.ump files for assembling the "random" maps and places the 'fixed' tiles. For a more detailed description of the whole algorithm see SV_AddMapTiles.
int SV_AssembleMap (const char *mapTheme, const char *assembly, char *asmTiles, char *asmPos, char *entityString, const unsigned int seed, bool print)
int SV_AssembleMapAndTitle (const char *mapTheme, const char *assembly, char *asmTiles, char *asmPos, char *entityString, const unsigned int seed, bool print, char *asmTitle)
void SV_PrintAssemblyStats (const char *mapTheme, const char *asmName)

Variables

static short posTileList [RMA2_MAX_REC][RMA2_MAX_TILEPOS]
 array of working random tile positions, 50 recursions
static short gapList [MAX_RANDOM_MAP_HEIGHT][MAX_RANDOM_MAP_HEIGHT][GAPS+1]
 for every x/y we can store the tiles that can cover that place here
static int minMissingSolids
static SDL_sem * mapSem
static SDL_cond * mapCond
static SDL_mutex * mapLock
static Uint32 threadID
static int availableTiles [MAX_TILETYPES][2]
 Select the next tile to place and place it (recursively).

Detailed Description

Random map assembly code More info on map-assembly can be found at: http://ufoai.org/wiki/index.php/Mapping/Random_map_assembly.

Definition in file sv_rma.cpp.

Macro Definition Documentation

◆ ACH

#define ACH   3 /* ascii cell height */

Definition at line 291 of file sv_rma.cpp.

Referenced by SV_RmaPrintMap().

◆ ACW

#define ACW   6 /* ascii cell width */

Definition at line 290 of file sv_rma.cpp.

Referenced by SV_RmaPrintMap().

◆ ALL_TILES

#define ALL_TILES   (0xfffffffeUL)

Definition at line 218 of file sv_rma.cpp.

Referenced by SV_ClearMap(), SV_CombineAlternatives(), SV_TileMaskToString(), and tileMask().

◆ ASSEMBLE_THREADS

#define ASSEMBLE_THREADS   2

Definition at line 37 of file sv_rma.cpp.

Referenced by SV_ParallelSearch().

◆ GAPS

#define GAPS   25

the # of different tiles we can store for a gap

Definition at line 64 of file sv_rma.cpp.

Referenced by SV_AddMissingTiles_r(), SV_GapCheckNeighbour(), SV_GapListBuild(), and SV_GapListReduce().

◆ IS_SOLID

◆ MAX_ASSEMBLY_SEEDS

#define MAX_ASSEMBLY_SEEDS   32

Definition at line 102 of file sv_rma.cpp.

◆ MAX_FIXEDTILES

#define MAX_FIXEDTILES   64

Definition at line 83 of file sv_rma.cpp.

Referenced by SV_ParseAssembly().

◆ MAX_MAPASSEMBLIES

#define MAX_MAPASSEMBLIES   32

Definition at line 76 of file sv_rma.cpp.

Referenced by SV_ParseUMP().

◆ MAX_RANDOM_MAP_HEIGHT

#define MAX_RANDOM_MAP_HEIGHT   32

◆ MAX_RANDOM_MAP_WIDTH

#define MAX_RANDOM_MAP_WIDTH   32

◆ MAX_TILESETS

#define MAX_TILESETS   16

Definition at line 80 of file sv_rma.cpp.

Referenced by SV_ParseUMP().

◆ MAX_TILESETTILES

#define MAX_TILESETTILES   16

Definition at line 81 of file sv_rma.cpp.

Referenced by SV_ParseMapTileSet().

◆ MAX_TILESIZE

#define MAX_TILESIZE   16

Definition at line 82 of file sv_rma.cpp.

Referenced by SV_FitTile(), and SV_ParseMapTile().

◆ MAX_TILETYPES

#define MAX_TILETYPES   128

note: MAX_TILETYPES mostly limits the # of tiles that can be parsed. The # used in an assemly is roughly limited to RMA2_MAX_REC (+fixed + required tiles).

Definition at line 79 of file sv_rma.cpp.

Referenced by SV_AddMissingTiles(), and SV_ParseUMP().

◆ MMH

#define MMH   13 /* map max height */

Definition at line 293 of file sv_rma.cpp.

Referenced by SV_RmaPrintMap().

◆ MMW

#define MMW   13 /* map max width 13 means we support 12 */

Definition at line 292 of file sv_rma.cpp.

Referenced by SV_RmaPrintMap().

◆ PRINT_RMA_PROGRESS

#define PRINT_RMA_PROGRESS   0

print some debugging info

Definition at line 39 of file sv_rma.cpp.

◆ RMA2_MAX_REC

#define RMA2_MAX_REC   64

max # of recursions

Definition at line 44 of file sv_rma.cpp.

Referenced by SV_AddMissingTiles_r().

◆ RMA2_MAX_TILEPOS

#define RMA2_MAX_TILEPOS   1700

max # of valid tile/position combinations

Definition at line 57 of file sv_rma.cpp.

Referenced by SV_AddMissingTiles(), and SV_AddMissingTiles_r().

◆ SORT_BY_SIZE

#define SORT_BY_SIZE   1

place the biggest 'required' tiles first. Helps oriental a lot, but is bad for village.

Definition at line 41 of file sv_rma.cpp.

◆ TCM

#define TCM   50

tile code multiplier. For the various debug printfs we want a number that we can easily divide through (20, 50, 100,...)

Definition at line 59 of file sv_rma.cpp.

Referenced by SV_AddMissingTiles(), SV_AddMissingTiles_r(), SV_GapGetFlagsAtAbsPos(), and SV_GapListBuild().

Function Documentation

◆ cmpTileAreaSize()

int cmpTileAreaSize ( const void * a,
const void * b )
static

Definition at line 2050 of file sv_rma.cpp.

Referenced by SV_DoMapAssemble().

◆ RandomList()

void RandomList ( const int n,
short * list )
static

Fills a list with random values between 0 and n.

Parameters
[in]nSize of the list
[out]listThe list to fill with random values

Definition at line 203 of file sv_rma.cpp.

References i.

Referenced by SV_AddMapTiles(), and SV_AddMissingTiles().

◆ SV_AddMapTiles()

bool SV_AddMapTiles ( MapInfo * map)
static

Tries to build the map There are 3 categories of tiles:

  • fixed: the position of the tile is already given in the assembly definition
  • required: a given number of such a tile must be placed somewhere on the map
  • optional: up to a given number of these tiles may be used in the map The algorithm works as follows: The fixed tiles have already been placed in the calling function. This function here now places the required tiles at random positions. Then the remaining gaps are filled with the optional tiles. If that fails, the last required tile is moved to a different place and the filling is tried again. If no more places are left for the required tile, the previous required tile is relocated and so on. That is, for the required tiles every possible combination is tried before we give up.
    Parameters
    mapAll we know about the map to assemble
    See also
    SV_FitTile
    SV_AddTile

Definition at line 1698 of file sv_rma.cpp.

References Com_Error(), Com_Printf(), Assembly::dx, Assembly::dy, ERR_DROP, MapInfo::getCurrentAssembly(), MapInfo::getName(), Assembly::id, mPlaced_t::idx, mapSem, mapStr, MAX_RANDOM_MAP_HEIGHT, MAX_RANDOM_MAP_WIDTH, MapInfo::mPlaced, MapInfo::mToPlace, MapInfo::numPlaced, Assembly::numSeeds, MapInfo::numToPlace, posStr, RandomList(), MapInfo::retryCnt, Assembly::size, SV_AddMissingTiles(), SV_AddTile(), SV_BuildMapStrings(), SV_FitTile(), SV_RemoveTile(), sv_rma, sv_rmadisplaythemap, SV_RmaPrintMap(), sv_threads, and Assembly::width.

Referenced by SV_AssemblyThread(), and SV_DoMapAssemble().

◆ SV_AddMissingTiles()

bool SV_AddMissingTiles ( MapInfo * map)
static

Tries to fill the missing tiles of the current map. While the 2010 algo used a 'by chance'-algo, this algo does a full tree search. Example: After placing the fixed and required tiles on a 8x8 map, we have say 32 places not yet covered by tiles. If there are 10 different tiles for each gap, we can have up to have 10^32 constellations to try. That's about one fantastillion. Impossible. Fortunately, there are usually many solutions to this puzzle. And we only need to find one working solution. But on some maps eg. 'forest large' with it's little brook, there are fewer solutions, so the search can take longer. In order to complete the search in a reasonable time, this algo uses several strategies:

  • reduce the number of available options to narrow the tree
  • direct the search towards those options that are more likely to fail. This can cut off a whole branch of the tree. Details will be explained along the call-tree
    Parameters
    mapAll we know about the map to assemble
    Returns
    false if the tiles does not fit, true if the map could be filled.
    See also
    SV_FitTile
    SV_AddTile

build a list of all positions of the map and all the tiles that fit there

try to reduce the number of available options

Definition at line 1572 of file sv_rma.cpp.

References Com_Printf(), Assembly::dx, Assembly::dy, gapList, MapInfo::getCurrentAssembly(), Assembly::height, i, m, mapStr, MAX_RANDOM_MAP_HEIGHT, MAX_RANDOM_MAP_WIDTH, MAX_TILETYPES, minMissingSolids, MapInfo::mToPlace, MapInfo::numPlaced, MapInfo::numToPlace, posStr, posTileList, RandomList(), RMA2_MAX_TILEPOS, Assembly::size, SV_AddMissingTiles_r(), SV_BuildMapStrings(), SV_FitTile(), SV_GapListBuild(), SV_GapListReduce(), SV_TestFilled(), TCM, and Assembly::width.

Referenced by SV_AddMapTiles().

◆ SV_AddMissingTiles_r()

bool SV_AddMissingTiles_r ( MapInfo * map,
int rec,
int posListCnt,
short myPosList[],
const Tile * prevTile,
int prevX,
int prevY )
static

calculate the area of the tile placed by the previous recursion

circle through the old list of available tile positions and store the remaining ones in the static array

try to reduce the # of calls to SV_FitTile by checking only those gaps affected by the placement of the previous tile

initialize the list of gaps

if the remaining tiles are simply not enough to cover the gaps, bail

check how well the remaining tiles can cover the gaps

if we find a gap that NO tile can cover, bail

if there is a gap that only ONE tile can cover, try that. If it doesn't work out, we're done.

if there is a gap that only TWO tiles can cover, try those two. If it doesn't work out, we're done. Then try with THREE and so on.

now try each of the remaining positions, that is, those that have more than GAPS alternatives. Rarely happens.

Definition at line 1186 of file sv_rma.cpp.

References Tile::area, availableTiles, mToPlace_t::cnt, Com_Printf(), MapInfo::curMap, gapList, GAPS, MapInfo::getCurrentAssembly(), Tile::h, Assembly::height, i, IS_SOLID, MapInfo::lineFlags, mToPlace_t::max, minMissingSolids, MapInfo::mToPlace, posTileList, RMA2_MAX_REC, RMA2_MAX_TILEPOS, Tile::spec, SV_AddMissingTiles_r(), SV_AddTile(), SV_FitTile(), SV_RemoveTile(), sv_rmadisplaythemap, SV_RmaPrintMap(), SV_TestFilled(), TCM, mToPlace_t::tile, Tile::w, and Assembly::width.

Referenced by SV_AddMissingTiles(), and SV_AddMissingTiles_r().

◆ SV_AddTile()

void SV_AddTile ( MapInfo * map,
const Tile * tile,
int x,
int y,
int idx,
int pos )
static

Adds a new map-tile to an assembled map. Also adds the tile to the placed-tiles list.

Note
The tile must fit at the given position, otherwise an assert will occur!
Parameters
[in,out]mapThe map that will get the tile. Modified in place.
[in]tileThe tile to add to the map.
[in]x,yThe position in the map where the tile should be placed.
[in]idxThe index of the placement algorithm.
[in]posThe position of the placement algorithm.
See also
SV_FitTile

Definition at line 1028 of file sv_rma.cpp.

References mToPlace_t::cnt, Com_Error(), MapInfo::curMap, Assembly::dx, Assembly::dy, ERR_DROP, MapInfo::getCurrentAssembly(), Tile::h, mPlaced_t::idx, MAX_RANDOM_MAP_HEIGHT, MAX_RANDOM_MAP_WIDTH, MapInfo::mPlaced, MapInfo::mToPlace, MapInfo::numPlaced, mPlaced_t::pos, Tile::spec, SV_CombineAlternatives(), mPlaced_t::tile, Tile::w, mPlaced_t::x, and mPlaced_t::y.

Referenced by SV_AddMapTiles(), SV_AddMissingTiles_r(), and SV_DoMapAssemble().

◆ SV_AssembleMap()

int SV_AssembleMap ( const char * mapTheme,
const char * assembly,
char * asmTiles,
char * asmPos,
char * entityString,
const unsigned int seed,
bool print )

◆ SV_AssembleMap_()

MapInfo * SV_AssembleMap_ ( const char * mapTheme,
const char * assembly,
char * asmTiles,
char * asmPos,
char * entityString,
const unsigned int seed,
bool print )
static

Assembles a "random" map and parses the *.ump files for assembling the "random" maps and places the 'fixed' tiles. For a more detailed description of the whole algorithm see SV_AddMapTiles.

Parameters
[in]mapThemeThe name of the map (ump) file to parse
[in]assemblyThe random map assembly that should be used from the given rma
[out]asmTilesThe output string of the random map assembly that contains all the map tiles that should be assembled. The order is the same as in the asmPos string. Each of the map tiles in this string has a corresponding entry in the pos string, too.
[out]asmPosThe pos string for the assembly. For each tile from the asmTiles string this string contains three coordinates for shifting the given tile names.
[out]entityStringAn entity string that is used for all map tiles. Parsed from the ump.
[in]seedrandom seed to use (for cunit tests). If 0, the called functions can use their own seed setting.
[in]printWhether or not extended output should be printed
See also
B_AssembleMap_f
SV_AddTile
SV_ParseAssembly
SV_ParseMapTile
Note
Make sure to free the returned pointer

Definition at line 2167 of file sv_rma.cpp.

References MapInfo::asmIdx, MapInfo::assemblies, Com_DPrintf(), Com_Error(), Com_Printf(), DEBUG_SERVER, ERR_DROP, MapInfo::getName(), i, Assembly::id, Mem_AllocType, MapInfo::numAssemblies, MapInfo::numTiles, Q_streq, Q_strvalid, MapInfo::setName(), SV_DoMapAssemble(), and SV_ParseUMP().

Referenced by SV_AssembleMap(), and SV_AssembleMapAndTitle().

◆ SV_AssembleMapAndTitle()

int SV_AssembleMapAndTitle ( const char * mapTheme,
const char * assembly,
char * asmTiles,
char * asmPos,
char * entityString,
const unsigned int seed,
bool print,
char * asmTitle )

Definition at line 2220 of file sv_rma.cpp.

References MapInfo::getCurrentAssemblyTitle(), Mem_Free, MapInfo::numPlaced, and SV_AssembleMap_().

Referenced by SV_Map().

◆ SV_AssemblyThread()

int SV_AssemblyThread ( void * data)
static

The main function for the threads that try to create random map assemblies in parallel.

Parameters
dataThe MapInfo structure local to this thread. Should be initialized by memcpy-ing the actual map into new memory. Not thread-safe to read or write, this thread assumes that nobody else will access the given copy of the map before the thread ends. It is the responsibility of the caller to free the map, if needed, after the thread has died and been collected.
Returns
0 on success, -1 if it was interrupted via the mapSem semaphore, signaling that someone else has finished first, or timeout occurred.

Definition at line 1835 of file sv_rma.cpp.

References Com_SetRandomSeed(), data, mapCond, mapLock, mapSem, MapInfo::retryCnt, SV_AddMapTiles(), and threadID.

Referenced by SV_ParallelSearch().

◆ SV_BuildMapStrings()

void SV_BuildMapStrings ( const MapInfo * map,
char * asmTiles,
char * asmPos,
bool print )
static

Creates the mapstrings as known from the ufoconsole.log and optionally prints them. This can also be used to dump the progress of the RMA process.

Parameters
[in]mapAll we know about the map to assemble
[out]asmTilesThe output string of the random map assembly that contains all the map tiles that should be assembled. The order is the same as in the asmPos string. Each of the map tiles in this string has a corresponding entry in the pos string, too.
[out]asmPosThe pos string for the assembly. For each tile from the asmTiles string asmPos contains three coordinates for shifting the given tile names.
[in]printPrint out the mapStrings or not

Definition at line 1126 of file sv_rma.cpp.

References Com_Printf(), MapInfo::getCurrentAssembly(), Assembly::height, i, Tile::id, MAX_TILESTRINGS, MAX_TOKEN_CHARS, MapInfo::mPlaced, MapInfo::numPlaced, Q_strcat(), sv_dumpmapassembly, SV_DumpPlaced(), mPlaced_t::tile, Assembly::width, mPlaced_t::x, and mPlaced_t::y.

Referenced by SV_AddMapTiles(), SV_AddMissingTiles(), and SV_DoMapAssemble().

◆ SV_ClearMap()

void SV_ClearMap ( MapInfo * map)
static

Reset the map to empty state.

Definition at line 910 of file sv_rma.cpp.

References ALL_TILES, MapInfo::curMap, MAX_RANDOM_MAP_HEIGHT, and MAX_RANDOM_MAP_WIDTH.

Referenced by SV_DoMapAssemble(), and SV_RemoveTile().

◆ SV_CombineAlternatives()

void SV_CombineAlternatives ( unsigned long * mapAlts,
const unsigned long tileAlts )
static

Combines the alternatives/connection info of a map with a tile and sets the rating.

Parameters
[in,out]mapAltsPointer to the alternatives info field of the map which will be updated.
[in]tileAltsPointer to the alternatives info field of the tile.
See also
SV_FitTile

Definition at line 892 of file sv_rma.cpp.

References ALL_TILES, and IS_SOLID.

Referenced by SV_AddTile(), and SV_RemoveTile().

◆ SV_DoMapAssemble()

◆ SV_DumpPlaced()

void SV_DumpPlaced ( const MapInfo * map,
int pl )
static

Debug function to dump the map location of a placed tile.

Definition at line 992 of file sv_rma.cpp.

References Com_Printf(), MapInfo::getCurrentAssembly(), Assembly::height, Tile::id, IS_SOLID, MapInfo::mPlaced, Tile::spec, mPlaced_t::tile, Assembly::width, mPlaced_t::x, and mPlaced_t::y.

Referenced by SV_BuildMapStrings().

◆ SV_FitTile()

bool SV_FitTile ( const MapInfo * map,
const Tile * tile,
const int x,
const int y )
static

Checks if a given map-tile fits into the empty space (in a given location) of a map.

Parameters
[in,out]mapAll we know about the map to assemble
[in]tileThe tile definition that should be fitted into the map.
[in]x,yThe position in the map where the tile is supposed to be placed/checked.
Returns
true if the tile fits, false if the tile does not fit or an error was encountered.

Definition at line 926 of file sv_rma.cpp.

References MapInfo::curMap, Assembly::dx, Assembly::dy, MapInfo::getCurrentAssembly(), Tile::h, Assembly::height, IS_SOLID, m, MAX_RANDOM_MAP_WIDTH, MAX_TILESIZE, Tile::spec, Tile::w, and Assembly::width.

Referenced by SV_AddMapTiles(), SV_AddMissingTiles(), and SV_AddMissingTiles_r().

◆ SV_GapCheckNeighbour()

bool SV_GapCheckNeighbour ( MapInfo * map,
int tc1,
int mapW,
int mapH,
int nx,
int ny )
static

Find a tile that meets the requirements of tc1 at a given pos.

Parameters
mapAll we know about the map to assemble
tc1encoded tile and position
mapWwidth of the map. Needed to decode tc1
mapHheight of the map. Needed to validate ny
nxx of the absolute map position to investigate
nyy of the absolute map position to investigate
Returns
true if no matching tile was found

circle through the tiles that cover this gap

Definition at line 1455 of file sv_rma.cpp.

References gapList, GAPS, IS_SOLID, and SV_GapGetFlagsAtAbsPos().

Referenced by SV_GapListReduce().

◆ SV_GapGetFlagsAtAbsPos()

unsigned long SV_GapGetFlagsAtAbsPos ( MapInfo * map,
int tileCode,
int mapW,
int mapX,
int mapY )
static

get the specs of a tile at map-x/y if it was placed where tileCode indicates

Parameters
mapAll we know about the map to assemble
tileCodeencoded tile and position
mapWwidth of the map. Needed to decode tileCode
mapXx of the gap
mapYy of the gap
Returns
the flags

Definition at line 1161 of file sv_rma.cpp.

References MapInfo::mToPlace, Tile::spec, TCM, and mToPlace_t::tile.

Referenced by SV_GapCheckNeighbour().

◆ SV_GapListBuild()

bool SV_GapListBuild ( MapInfo * map,
int tilePosListCnt )
static

Builds a list of map positions (gaps) and the tiles that can cover them.

Note
actually it's not a list but a 3D-array
Parameters
mapAll we know about the map to assemble
tilePosListCntThe number of remaining possible tile positions
Returns
false if we detect a gap that NO tile can cover

initialize the list of gaps

if we find a gap that NO tile can cover, bail

Definition at line 1400 of file sv_rma.cpp.

References MapInfo::curMap, gapList, GAPS, MapInfo::getCurrentAssembly(), Tile::h, Assembly::height, i, IS_SOLID, MapInfo::mToPlace, posTileList, Tile::spec, TCM, mToPlace_t::tile, Tile::w, and Assembly::width.

Referenced by SV_AddMissingTiles().

◆ SV_GapListReduce()

int SV_GapListReduce ( MapInfo * map)
static

Tries to find tiles that exclude all of their neighbours This is called only once, before recursion starts. So we can safely (ab)use the posTileList space for recursion 1.

Parameters
mapAll we know about the map to assemble
Returns
the number of tiles that could be eliminated

number of tiles marked for elinimation

if there is a tile that doesn't match ANY of the tiles available for the adjacent gap we can eliminate it.

Definition at line 1500 of file sv_rma.cpp.

References gapList, GAPS, MapInfo::getCurrentAssembly(), Assembly::height, posTileList, SV_GapCheckNeighbour(), and Assembly::width.

Referenced by SV_AddMissingTiles().

◆ SV_GetCvarToken()

const char * SV_GetCvarToken ( const MapInfo * map,
const Assembly * a,
const char * token,
const char * filename,
const char ** text,
const char * errhead )
static

Tries to extract a tile name from a cvar - the cvar value must start with a '+'.

Parameters
[in,out]mapAll we know about the map to assemble
athe assembly
tokenThe cvar name
filenameThe ump filename
textThe text buffer
errheadError header
Returns
nullptr if file has invalid format, the tilename of the cvar otherwise.

Definition at line 572 of file sv_rma.cpp.

References Com_DPrintf(), Com_EParse(), Com_Error(), Com_Printf(), Cvar_FindVar(), Cvar_Set(), DEBUG_SERVER, ERR_DROP, i, Assembly::id, Tile::id, MapInfo::mTile, cvar_t::name, MapInfo::numTiles, Q_strncasecmp, and cvar_t::string.

Referenced by SV_ParseAssembly().

◆ SV_GetMapTile()

const Tile * SV_GetMapTile ( const MapInfo * map,
const char * tileName )
inlinestatic

◆ SV_GetMapTileSet()

const TileSet * SV_GetMapTileSet ( const MapInfo * map,
const char * tileSetName )
static

Definition at line 403 of file sv_rma.cpp.

References i, TileSet::id, MapInfo::numTileSets, Q_streq, and MapInfo::tileSets.

Referenced by SV_GetTileFromTileSet(), and SV_GetTilesFromTileSet().

◆ SV_GetTileFromTileSet()

const char * SV_GetTileFromTileSet ( const MapInfo * map,
const char * filename,
const char ** text,
const Assembly * a )
static

◆ SV_GetTilesFromTileSet()

void SV_GetTilesFromTileSet ( const MapInfo * map,
const char * filename,
const char ** text,
Assembly * a )
static

◆ SV_ParallelSearch()

int SV_ParallelSearch ( MapInfo * map)
static

Spawn ASSEMBLE_THREADS threads to try and assemble a map. The first map complete gets returned. Allocates a new copy of the map for each thread, and frees it at the end. Uses a timeout (initially 5 seconds). If the spawned threads have not completed by the timeout, they are restarted, with double the timeout.

Note
The algorithm main points: The synchronization of threads happens using a semaphore mapSem, a lock mapLock, and a condition mapCond. The semaphore is initially 1 (and reset to 1 every time there is a restart). The first thread that finishes, grabs the semaphore, to tell all other threads to abort. All threads test the semaphore, if it is 0, they abort. After the timeout, the main thread grabs the semaphore, to make everybody conclude, and then restarts them. The lock is used to protect writes to the threadID global variable, that holds the ID of the thread which finished, if any. It is also used to protect the conditional mapCond, used by the finished thread to notify the main() thread, so it can collect all threads and copy the final map back to the caller. The lock is locked by main() at all times, unless it is waiting on the conditional (with timeout). When an assembler thread finishes, it grabs the lock (which means main() is still waiting), writes its ID to threadID, signals main() and releases the lock. main() gets the signal after the lock is released, since the signal is protected by the lock, so there can be no race between finishing assembly and signaling main() for the assembler threads. When a timeout occurs, main() exits the conditional by grabbing the lock again. This will prevent any thread from exiting, even if it finishes between the time that main() timed out and the time it tries to get the semaphore. So, main() checks the semaphore to see if it is taken, and if so doesn't restart, despite the timeout.
Todo
Maybe we also need to reduce the timeout value a bit every time it succeeds?

Definition at line 1884 of file sv_rma.cpp.

References ASSEMBLE_THREADS, Com_CreateThread(), Com_Printf(), i, mapCond, mapLock, mapSem, Mem_AllocType, Mem_Free, SV_AssemblyThread(), sv_threads, and threadID.

Referenced by SV_DoMapAssemble().

◆ SV_ParseAssembly()

bool SV_ParseAssembly ( MapInfo * map,
const char * filename,
const char ** text,
Assembly * a )
static

Parses an assembly block.

Parameters
[in,out]mapAll we know about the map to assemble
[in]filenameThe name of the .UMP file, used in error messages
[out]aPointer to the assembly to be initialized, must be allocated.
[in]textThe text of the ump file to parse
See also
SV_ParseMapTile
Note
: format of size: "size x y"
: format of fix: "fix [tilename] x y"
: format of tile: "[tilename] min max"
Returns
true if it was parsed, false if not.

Definition at line 727 of file sv_rma.cpp.

References Com_EParse(), Com_Error(), Assembly::dx, Assembly::dy, ERR_DROP, Assembly::fT, Assembly::fX, Assembly::fY, Assembly::height, i, Assembly::id, Tile::id, Assembly::max, MAX_FIXEDTILES, MAX_RANDOM_MAP_HEIGHT, MAX_RANDOM_MAP_WIDTH, Assembly::min, MapInfo::mTile, Assembly::numFixed, OBJZERO, Q_streq, Q_strncpyz(), Assembly::size, SV_GetCvarToken(), SV_GetMapTile(), SV_GetTileFromTileSet(), SV_GetTilesFromTileSet(), sv_maxclients, SV_ParseAssemblySeeds(), Assembly::title, and Assembly::width.

Referenced by SV_ParseUMP().

◆ SV_ParseAssemblySeeds()

bool SV_ParseAssemblySeeds ( MapInfo * map,
const char * filename,
const char ** text,
Assembly * a )
static

Parses a list of working seeds to assemble this rma assembly.

Parameters
[in,out]mapAll we know about the map to assemble
[in]filenameThe name of the .UMP file, used in error messages
[out]aPointer to the assembly to be initialized, must be allocated.
[in]textThe text of the ump file to parse
Returns
true if it was parsed, false if not.

Definition at line 644 of file sv_rma.cpp.

References Com_EParse(), Com_Printf(), Assembly::id, lengthof, Assembly::numSeeds, and Assembly::seeds.

Referenced by SV_ParseAssembly().

◆ SV_ParseMapTile()

bool SV_ParseMapTile ( const char * filename,
const char ** text,
MapInfo * map,
bool inherit )
static

Parsed a tile definition out of the ump-files.

See also
SV_ParseAssembly

Definition at line 488 of file sv_rma.cpp.

References Tile::area, Com_EParse(), Com_Printf(), Com_sprintf(), Tile::h, i, Tile::id, MapInfo::inheritBasePath, IS_SOLID, MAX_TILESIZE, MapInfo::mTile, MapInfo::numTiles, OBJZERO, Q_strncpyz(), Tile::spec, tileMask(), and Tile::w.

Referenced by SV_ParseUMP().

◆ SV_ParseMapTileSet()

bool SV_ParseMapTileSet ( const char * filename,
const char ** text,
MapInfo * map,
bool inherit )
static

◆ SV_ParseUMP()

void SV_ParseUMP ( const char * name,
char * entityString,
MapInfo * map,
bool inherit )
static

Parses an ump file that contains the random map definition.

Parameters
[in]nameThe basename of the ump file (without extension)
[out]mapThe data structure to store the parsed data in
[in]inheritWhen true, this is called to inherit tile definitions
[out]entityStringAn entity string that is used for all map tiles. Parsed from the ump. from another ump file (no assemblies)

Definition at line 1965 of file sv_rma.cpp.

References MapInfo::assemblies, MapInfo::basePath, Com_Error(), Com_GetBlock(), Com_Parse(), Com_Printf(), Com_SkipBlock(), Com_sprintf(), CS_ENTITYSTRING, ERR_DROP, FS_FreeFile(), FS_LoadFile(), MapInfo::inheritBasePath, length, MapInfo::lineFlags, MAX_MAPASSEMBLIES, MAX_QPATH, MAX_TILESETS, MAX_TILETYPES, name, MapInfo::numAssemblies, MapInfo::numTiles, MapInfo::numTileSets, Q_streq, Q_strncpyz(), SV_GetConfigStringLength(), SV_ParseAssembly(), SV_ParseMapTile(), SV_ParseMapTileSet(), SV_ParseUMP(), and tileMask().

Referenced by SV_AssembleMap_(), SV_ParseUMP(), and SV_PrintAssemblyStats().

◆ SV_PrepareTilesToPlace()

void SV_PrepareTilesToPlace ( MapInfo * map)
static

◆ SV_PrintAssemblyStats()

◆ SV_RemoveTile()

void SV_RemoveTile ( MapInfo * map,
int * idx,
int * pos )
static

Rebuilds a assembled map up to the previous tile.

Parameters
[in,out]mapAll we know about the map to assemble
[out]idxPointer to the location to store the index field of the removed tile
[out]posPointer to the location to store the position field of the removed tile
See also
SV_AddTile
SV_FitTile

Definition at line 1073 of file sv_rma.cpp.

References mToPlace_t::cnt, MapInfo::curMap, Tile::h, i, mPlaced_t::idx, index, MAX_RANDOM_MAP_HEIGHT, MAX_RANDOM_MAP_WIDTH, MapInfo::mPlaced, MapInfo::mToPlace, MapInfo::numPlaced, mPlaced_t::pos, Tile::spec, SV_ClearMap(), SV_CombineAlternatives(), mPlaced_t::tile, Tile::w, mPlaced_t::x, and mPlaced_t::y.

Referenced by SV_AddMapTiles(), and SV_AddMissingTiles_r().

◆ SV_RmaPrintMap()

◆ SV_TestFilled()

bool SV_TestFilled ( const MapInfo * map)
static

Checks if the map is completely filled.

Returns
true if the map is filled, false if the map has still empty fields
See also
SV_FitTile

Definition at line 976 of file sv_rma.cpp.

References MapInfo::curMap, MapInfo::getCurrentAssembly(), Assembly::height, IS_SOLID, and Assembly::width.

Referenced by SV_AddMissingTiles(), and SV_AddMissingTiles_r().

◆ SV_TileMaskToString()

void SV_TileMaskToString ( unsigned long m,
char * str )
static

Definition at line 261 of file sv_rma.cpp.

References ALL_TILES, i, and m.

Referenced by SV_RmaPrintMap().

◆ tileMask()

unsigned long tileMask ( const char chr)
static

Convert to tile spec - normalize the characters.

See also
SV_ParseMapTile
Note
a tile definition looks like this:
tile +s02
{
3 3
0 a 0
b +b b
0 a 0
}
tile +s02 defines the name of the tile which can be refered to from the assembly the first two numbers defines the tile size - if you have a tile with the 'real' size of 1x1 (256x256 in radiant) the definition is 3x3 because you have to define the surroundings, too The field marked with the + is the 'real' mapparts all the others are the surroundings - the letters of the surroundings must have a tile definition with a + and the letter, too - otherwise the placing of the tile may fail
If you marked a tile with + the Tile->spec at that position will be SOLID
valid tile characters are 0-5 and a-z

Definition at line 245 of file sv_rma.cpp.

References ALL_TILES, Com_Error(), and ERR_DROP.

Referenced by SV_ParseMapTile(), and SV_ParseUMP().

Variable Documentation

◆ availableTiles

int availableTiles[MAX_TILETYPES][2]
static

Select the next tile to place and place it (recursively).

Parameters
mapAll we know about the map to assemble
recThe number of the current recursion
posListCntThe number of remaining tile position (=options)
myPosListThe previous list of remaining tile position (=options)
prevTileThe tile placed by the previous recursion
prevXx where it was placed
prevYwell, y
Returns
false if the tiles do not fit, true if the map could be filled.

Definition at line 1184 of file sv_rma.cpp.

Referenced by SV_AddMissingTiles_r().

◆ gapList

for every x/y we can store the tiles that can cover that place here

Definition at line 68 of file sv_rma.cpp.

Referenced by SV_AddMissingTiles(), SV_AddMissingTiles_r(), SV_GapCheckNeighbour(), SV_GapListBuild(), and SV_GapListReduce().

◆ mapCond

SDL_cond* mapCond
static

Definition at line 72 of file sv_rma.cpp.

Referenced by SV_AssemblyThread(), and SV_ParallelSearch().

◆ mapLock

SDL_mutex* mapLock
static

Definition at line 73 of file sv_rma.cpp.

Referenced by SV_AssemblyThread(), and SV_ParallelSearch().

◆ mapSem

SDL_sem* mapSem
static

Definition at line 71 of file sv_rma.cpp.

Referenced by SV_AddMapTiles(), SV_AssemblyThread(), and SV_ParallelSearch().

◆ minMissingSolids

int minMissingSolids
static

Definition at line 70 of file sv_rma.cpp.

Referenced by SV_AddMissingTiles(), and SV_AddMissingTiles_r().

◆ posTileList

short posTileList[RMA2_MAX_REC][RMA2_MAX_TILEPOS]
static

array of working random tile positions, 50 recursions

Definition at line 61 of file sv_rma.cpp.

Referenced by SV_AddMissingTiles(), SV_AddMissingTiles_r(), SV_GapListBuild(), and SV_GapListReduce().

◆ threadID

Uint32 threadID
static

Definition at line 74 of file sv_rma.cpp.

Referenced by SV_AssemblyThread(), and SV_ParallelSearch().