sv_rma.c File Reference

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

#include "server.h"
#include "sv_rma.h"
#include "../shared/parse.h"
#include "SDL_thread.h"
Include dependency graph for sv_rma.c:

Go to the source code of this file.

Defines

#define ASSEMBLE_THREADS   2
#define ALL_TILES   (0xfffffffeUL)
#define IS_SOLID(x)   ((x)&1UL)
#define CHECK_ALTERNATIVES_COUNT   10
 Number of test alternatives per step in SV_AddMissingTiles.

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 const mTileSet_tSV_GetMapTileSet (const mapInfo_t *map, const char *tileSetName)
static const mTile_tSV_GetMapTile (const mapInfo_t *map, const char *tileName)
static qboolean SV_ParseMapTileSet (const char *filename, const char **text, mapInfo_t *map, qboolean inherit)
 Parsed a tileset definition out of the ump-files.
static qboolean SV_ParseMapTile (const char *filename, const char **text, mapInfo_t *map, qboolean inherit)
 Parsed a tile definition out of the ump-files.
static const char * SV_GetCvarToken (const mAssembly_t *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_t *map, const char *filename, const char **text, const mAssembly_t *a)
static qboolean SV_ParseAssembly (mapInfo_t *map, const char *filename, const char **text, mAssembly_t *a)
 Parses an assembly block.
static void SV_CombineAlternatives (unsigned long *mapAlts, const unsigned long tileAlts, char *mapRating)
 Combines the alternatives/connection info of a map with a tile and sets the rating.
static void SV_ClearMap (mapInfo_t *map)
 Reset the map to empty state.
static qboolean SV_FitTile (const mapInfo_t *map, mTile_t *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 qboolean SV_TestFilled (const mapInfo_t *map)
 Checks if the map is completely filled.
static void SV_DumpRating (const mapInfo_t *map)
 Debug fuction to dump the rating of the current map.
static void SV_DumpPlaced (const mapInfo_t *map, int pl)
 Debug function to dump the map location of a placed tile.
static int SV_CalcRating (const mapInfo_t *map)
 Returns the rating of the given map.
static void SV_AddTile (mapInfo_t *map, const mTile_t *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_t *map, int *idx, int *pos)
 Rebuilds a assembled map up to the previous tile.
static qboolean SV_PickRandomTile (mapInfo_t *map, int *idx, int *pos)
 Tries to fit a tile in the current map.
static qboolean SV_AddMissingTiles (mapInfo_t *map)
 Tries to fill the missing tiles of the current map.
static void SV_AddMapTiles (mapInfo_t *map)
 Tries to build the map.
static void SV_PrepareTilesToPlace (mapInfo_t *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_t *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, mapInfo_t *map, qboolean inherit)
 Parses an ump file that contains the random map definition.
mapInfo_tSV_AssembleMap (const char *name, const char *assembly, char *asmMap, char *asmPos)
 Assembles a "random" map parses the *.ump files for assembling the "random" maps.

Variables

static SDL_sem * mapSem
static SDL_cond * mapCond
static SDL_mutex * mapLock
static Uint32 threadID

Detailed Description

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

Definition in file sv_rma.c.


Define Documentation

#define ALL_TILES   (0xfffffffeUL)

Definition at line 63 of file sv_rma.c.

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

#define ASSEMBLE_THREADS   2

Definition at line 37 of file sv_rma.c.

Referenced by SV_ParallelSearch().

#define CHECK_ALTERNATIVES_COUNT   10

Number of test alternatives per step in SV_AddMissingTiles.

See also:
SV_AddMissingTiles

Definition at line 815 of file sv_rma.c.

Referenced by SV_AddMissingTiles().

#define IS_SOLID (  )     ((x)&1UL)

Definition at line 64 of file sv_rma.c.

Referenced by SV_CombineAlternatives(), SV_DumpPlaced(), SV_FitTile(), and SV_TestFilled().


Function Documentation

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

Fills a list with random values between 0 and n.

Parameters:
[in] n Size of the list
[out] list The list to fill with random values

Definition at line 48 of file sv_rma.c.

References i.

Referenced by SV_AddMapTiles().

static void SV_AddMapTiles ( mapInfo_t map  )  [static]
static qboolean SV_AddMissingTiles ( mapInfo_t map  )  [static]

Tries to fill the missing tiles of the current map.

Returns:
false if the tiles does not fit, true if the map could be filled.
See also:
SV_FitTile
SV_AddTile

Definition at line 823 of file sv_rma.c.

References CHECK_ALTERNATIVES_COUNT, mAssembly_s::height, i, mapInfo_s::mAsm, mapInfo_s::mAssembly, mapInfo_s::mToPlace, pos, qfalse, qtrue, SV_AddTile(), SV_CalcRating(), SV_PickRandomTile(), SV_RemoveTile(), SV_TestFilled(), and mAssembly_s::width.

Referenced by SV_AddMapTiles().

static void SV_AddTile ( mapInfo_t map,
const mTile_t 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 occure!
Parameters:
[in,out] map The map that will get the tile. Modified in place.
[in] tile The tile to add to the map.
[in] x The x position in the map where the tile should be placed.
[in] y The y position in the map where the tile should be placed.
[in] idx The index of the placement algorithm.
[in] pos The position of the placement algorithm.
See also:
SV_AssembleMap
SV_AddRegion
SV_FitTile

Definition at line 680 of file sv_rma.c.

References mToPlace_s::cnt, Com_Error(), mapInfo_s::curMap, mapInfo_s::curRating, mAssembly_s::dx, mAssembly_s::dy, ERR_DROP, mTile_s::h, mPlaced_s::idx, mapInfo_s::mAsm, mapInfo_s::mAssembly, MAX_RANDOM_MAP_HEIGHT, MAX_RANDOM_MAP_WIDTH, mapInfo_s::mPlaced, mapInfo_s::mToPlace, mapInfo_s::numPlaced, mPlaced_s::pos, mTile_s::spec, SV_CombineAlternatives(), mPlaced_s::tile, mTile_s::w, mPlaced_s::x, and mPlaced_s::y.

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

mapInfo_t* SV_AssembleMap ( const char *  name,
const char *  assembly,
char *  asmMap,
char *  asmPos 
)

Assembles a "random" map parses the *.ump files for assembling the "random" maps.

Parameters:
[in] name The name of the map (ump) file to parse
[in] assembly The random map assembly that should be used from the given rma
[out] asmMap The 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] asmPos The pos string for the assembly. For each tile from the asmMap string this string contains three coordinates for shifting the given tile names.
See also:
B_AssembleMap_f
SV_AddTile
SV_AddMandatoryParts
SV_ParseAssembly
SV_ParseMapTile
Note:
Make sure to free the returned pointer

Definition at line 1195 of file sv_rma.c.

References mapInfo_s::basePath, Com_DPrintf(), Com_Error(), Com_Printf(), Com_sprintf(), DEBUG_SERVER, ERR_DROP, mAssembly_s::fT, mAssembly_s::fX, mAssembly_s::fY, mAssembly_s::height, i, mTile_s::id, mAssembly_s::id, cvar_s::integer, map, mapInfo_s::mAsm, mapInfo_s::mAssembly, MAX_RANDOM_MAP_HEIGHT, MAX_RANDOM_MAP_WIDTH, MAX_TILESTRINGS, MAX_TOKEN_CHARS, Mem_Alloc, Mem_Free, mapInfo_s::mPlaced, mapInfo_s::mTile, mapInfo_s::name, mapInfo_s::numAssemblies, mAssembly_s::numFixed, mapInfo_s::numPlaced, mapInfo_s::numTiles, Q_strcat(), Q_strncpyz(), qfalse, SV_AddMapTiles(), SV_AddTile(), SV_ClearMap(), sv_dumpmapassembly, SV_DumpPlaced(), SV_ParallelSearch(), SV_ParseUMP(), SV_PrepareTilesToPlace(), sv_threads, mPlaced_s::tile, va(), mAssembly_s::width, mPlaced_s::x, and mPlaced_s::y.

Referenced by SV_Map(), testAssembly(), testMassAssemblyParallel(), testMassAssemblySequential(), and testMassAssemblyTimeout().

static int SV_AssemblyThread ( void *  data  )  [static]

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

Parameters:
data The mapInfo_t 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 occured.

Definition at line 994 of file sv_rma.c.

References map, mapCond, mapLock, mapSem, SV_AddMapTiles(), and threadID.

Referenced by SV_ParallelSearch().

static int SV_CalcRating ( const mapInfo_t map  )  [static]

Returns the rating of the given map.

Returns:
A value which roughly describes the connection quality of the map
See also:
SV_AssembleMap
SV_AddRegion
SV_FitTile

Definition at line 652 of file sv_rma.c.

References mapInfo_s::curRating, mAssembly_s::height, cvar_s::integer, mapInfo_s::mAsm, mapInfo_s::mAssembly, sv_dumpmapassembly, SV_DumpRating(), and mAssembly_s::width.

Referenced by SV_AddMissingTiles().

static void SV_ClearMap ( mapInfo_t map  )  [static]

Reset the map to empty state.

Definition at line 518 of file sv_rma.c.

References ALL_TILES, mapInfo_s::curMap, mapInfo_s::curRating, MAX_RANDOM_MAP_HEIGHT, and MAX_RANDOM_MAP_WIDTH.

Referenced by SV_AssembleMap(), and SV_RemoveTile().

static void SV_CombineAlternatives ( unsigned long *  mapAlts,
const unsigned long  tileAlts,
char *  mapRating 
) [static]

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

Parameters:
[in,out] mapAlts Pointer to the alternatives info field of the map which will be updated.
[in] tileAlts Pointer to the alternatives info field of the tile.
[in,out] mapRating Pointer to the rating field of the map.
See also:
SV_AssembleMap
SV_AddRegion
SV_FitTile

Definition at line 495 of file sv_rma.c.

References ALL_TILES, and IS_SOLID.

Referenced by SV_AddTile(), and SV_RemoveTile().

static void SV_DumpPlaced ( const mapInfo_t map,
int  pl 
) [static]

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

Definition at line 618 of file sv_rma.c.

References Com_Printf(), mAssembly_s::height, mTile_s::id, IS_SOLID, mapInfo_s::mAsm, mapInfo_s::mAssembly, mapInfo_s::mPlaced, mTile_s::spec, mPlaced_s::tile, mAssembly_s::width, mPlaced_s::x, and mPlaced_s::y.

Referenced by SV_AssembleMap().

static void SV_DumpRating ( const mapInfo_t map  )  [static]

Debug fuction to dump the rating of the current map.

Definition at line 601 of file sv_rma.c.

References Com_Printf(), mapInfo_s::curRating, mAssembly_s::height, mapInfo_s::mAsm, mapInfo_s::mAssembly, and mAssembly_s::width.

Referenced by SV_CalcRating().

static qboolean SV_FitTile ( const mapInfo_t map,
mTile_t 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] map All we know about the map to assemble
[in] tile The tile definition that should be fitted into the map.
[in] x The x position in the map where the tile is supposed to be placed/checked.
[in] y The y position in the map where the tile is supposed to be placed/checked.
Returns:
qtrue if the tile fits.
qfalse if the tile does not fit or an error was encountered.
See also:
SV_AddMandatoryParts
SV_AddRegion

Definition at line 540 of file sv_rma.c.

References mapInfo_s::curMap, mAssembly_s::dx, mAssembly_s::dy, mTile_s::h, mAssembly_s::height, IS_SOLID, m, mapInfo_s::mAsm, mapInfo_s::mAssembly, MAX_RANDOM_MAP_WIDTH, MAX_TILESIZE, qfalse, qtrue, mTile_s::spec, mTile_s::w, and mAssembly_s::width.

Referenced by SV_AddMapTiles(), and SV_PickRandomTile().

static const char* SV_GetCvarToken ( const mAssembly_t 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:
a the assembly
token The cvar name
filename The ump filename
text The text buffer
errhead Error header
Returns:
NULL if file has invalid format, the tilename of the cvar otherwise.

Definition at line 271 of file sv_rma.c.

References Com_DPrintf(), Com_EParse(), Com_Error(), Com_Printf(), Cvar_FindVar(), Cvar_Set(), DEBUG_SERVER, ERR_DROP, mAssembly_s::id, cvar_s::name, and cvar_s::string.

Referenced by SV_ParseAssembly().

static const mTile_t* SV_GetMapTile ( const mapInfo_t map,
const char *  tileName 
) [inline, static]

Definition at line 117 of file sv_rma.c.

References i, mTile_s::id, mapInfo_s::mTile, and mapInfo_s::numTiles.

Referenced by SV_ParseAssembly(), and SV_ParseMapTileSet().

static const mTileSet_t* SV_GetMapTileSet ( const mapInfo_t map,
const char *  tileSetName 
) [static]

Definition at line 106 of file sv_rma.c.

References i, mTileSet_s::id, mapInfo_s::mTileSets, and mapInfo_s::numTileSets.

Referenced by SV_GetTileFromTileSet().

static const char* SV_GetTileFromTileSet ( const mapInfo_t map,
const char *  filename,
const char **  text,
const mAssembly_t a 
) [inline, static]
static int SV_ParallelSearch ( mapInfo_t 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 1041 of file sv_rma.c.

References ASSEMBLE_THREADS, Com_Printf(), i, cvar_s::integer, mapCond, mapLock, mapSem, Mem_Alloc, Mem_Free, SV_AssemblyThread(), sv_threads, and threadID.

Referenced by SV_AssembleMap().

static qboolean SV_ParseAssembly ( mapInfo_t map,
const char *  filename,
const char **  text,
mAssembly_t a 
) [static]

Parses an assembly block.

Parameters:
[in,out] map All we know about the map to assemble
[in] filename The name of the .UMP file, used in error messages
[out] a Pointer to the assembly to be initialized, must be allocated.
[in] text The text of the ump file to parse
See also:
SV_AssembleMap
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 332 of file sv_rma.c.

References Com_EParse(), Com_Error(), mAssembly_s::dx, mAssembly_s::dy, ERR_DROP, mAssembly_s::fT, mAssembly_s::fX, mAssembly_s::fY, mAssembly_s::height, i, mTile_s::id, mAssembly_s::id, cvar_s::integer, mAssembly_s::max, MAX_FIXEDTILES, MAX_RANDOM_MAP_HEIGHT, MAX_RANDOM_MAP_WIDTH, mAssembly_s::min, mapInfo_s::mTile, mAssembly_s::numFixed, Q_strncpyz(), qfalse, qtrue, mAssembly_s::size, SV_GetCvarToken(), SV_GetMapTile(), SV_GetTileFromTileSet(), sv_maxclients, mAssembly_s::title, and mAssembly_s::width.

Referenced by SV_ParseUMP().

static qboolean SV_ParseMapTile ( const char *  filename,
const char **  text,
mapInfo_t map,
qboolean  inherit 
) [static]
static qboolean SV_ParseMapTileSet ( const char *  filename,
const char **  text,
mapInfo_t map,
qboolean  inherit 
) [static]
static void SV_ParseUMP ( const char *  name,
mapInfo_t map,
qboolean  inherit 
) [static]

Parses an ump file that contains the random map definition.

Parameters:
[in] name The basename of the ump file (without extension)
[out] map The data structure to store the parsed data in
[in] inherit When true, this is called to inherit tile definitions from another ump file (no assemblies)

Definition at line 1117 of file sv_rma.c.

References mapInfo_s::basePath, byte, Com_Error(), Com_Parse(), Com_Printf(), Com_sprintf(), ERR_DROP, FS_FreeFile(), FS_LoadFile(), FS_SkipBlock(), mapInfo_s::inheritBasePath, mapInfo_s::mAssembly, MAX_MAPASSEMBLIES, MAX_QPATH, MAX_TILESETS, MAX_TILETYPES, mapInfo_s::numAssemblies, mapInfo_s::numTiles, mapInfo_s::numTileSets, Q_strncpyz(), qtrue, SV_ParseAssembly(), SV_ParseMapTile(), and SV_ParseMapTileSet().

Referenced by SV_AssembleMap().

static qboolean SV_PickRandomTile ( mapInfo_t map,
int *  idx,
int *  pos 
) [static]

Tries to fit a tile in the current map.

Returns:
qtrue if a fitting tile was found.
qfalse if no tile fits.
See also:
SV_FitTile
SV_AddTile

Definition at line 775 of file sv_rma.c.

References mAssembly_s::dx, mAssembly_s::dy, mapInfo_s::mAsm, mapInfo_s::mAssembly, mapInfo_s::mToPlace, mapInfo_s::numToPlace, qfalse, qtrue, mAssembly_s::size, SV_FitTile(), and mAssembly_s::width.

Referenced by SV_AddMissingTiles().

static void SV_PrepareTilesToPlace ( mapInfo_t map  )  [static]
static void SV_RemoveTile ( mapInfo_t map,
int *  idx,
int *  pos 
) [static]

Rebuilds a assembled map up to the previous tile.

Parameters:
[in,out] map All we know about the map to assemble
[out] idx Pointer to the location to store the index field of the removed tile
[out] pos Pointer to the location to store the position field of the removed tile
See also:
SV_AssembleMap
SV_AddTile
SV_FitTile

Definition at line 726 of file sv_rma.c.

References mToPlace_s::cnt, mapInfo_s::curMap, mapInfo_s::curRating, mTile_s::h, i, mPlaced_s::idx, MAX_RANDOM_MAP_HEIGHT, MAX_RANDOM_MAP_WIDTH, mapInfo_s::mPlaced, mapInfo_s::mToPlace, mapInfo_s::numPlaced, mPlaced_s::pos, mTile_s::spec, SV_ClearMap(), SV_CombineAlternatives(), mPlaced_s::tile, mTile_s::w, mPlaced_s::x, and mPlaced_s::y.

Referenced by SV_AddMapTiles(), and SV_AddMissingTiles().

static qboolean SV_TestFilled ( const mapInfo_t map  )  [static]

Checks if the map is completely filled.

Returns:
qtrue if the map is filled
qfalse if the map has still empty fields
See also:
SV_AssembleMap
SV_AddRegion
SV_FitTile

Definition at line 585 of file sv_rma.c.

References mapInfo_s::curMap, mAssembly_s::height, IS_SOLID, mapInfo_s::mAsm, mapInfo_s::mAssembly, qfalse, qtrue, and mAssembly_s::width.

Referenced by SV_AddMissingTiles().

static 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 mTile_t->spec at that position will be SOLID
valid tile characters are 0-5 and a-z

Definition at line 90 of file sv_rma.c.

References ALL_TILES, Com_Error(), and ERR_DROP.

Referenced by SV_ParseMapTile().


Variable Documentation

SDL_cond* mapCond [static]

Definition at line 39 of file sv_rma.c.

Referenced by SV_AssemblyThread(), and SV_ParallelSearch().

SDL_mutex* mapLock [static]

Definition at line 40 of file sv_rma.c.

Referenced by SV_AssemblyThread(), and SV_ParallelSearch().

SDL_sem* mapSem [static]

Definition at line 38 of file sv_rma.c.

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

Uint32 threadID [static]

Definition at line 41 of file sv_rma.c.

Referenced by SV_AssemblyThread(), and SV_ParallelSearch().


Generated by  doxygen 1.6.2