+#define IN_GFX_FIELD_PLAY(x, y) (x >= gfx.sx && x < gfx.sx + gfx.sxsize && \
+ y >= gfx.sy && y < gfx.sy + gfx.sysize)
+#define IN_GFX_FIELD_FULL(x, y) (x >= gfx.real_sx && \
+ x < gfx.real_sx + gfx.full_sxsize && \
+ y >= gfx.real_sy && \
+ y < gfx.real_sy + gfx.full_sysize)
+#define IN_GFX_DOOR_1(x, y) (x >= gfx.dx && x < gfx.dx + gfx.dxsize && \
+ y >= gfx.dy && y < gfx.dy + gfx.dysize)
+#define IN_GFX_DOOR_2(x, y) (x >= gfx.vx && x < gfx.vx + gfx.vxsize && \
+ y >= gfx.vy && y < gfx.vy + gfx.vysize)
+#define IN_GFX_DOOR_3(x, y) (x >= gfx.ex && x < gfx.ex + gfx.exsize && \
+ y >= gfx.ey && y < gfx.ey + gfx.eysize)
+
+// values for mouse cursor
+#define CURSOR_UNDEFINED -1
+#define CURSOR_DEFAULT 0
+#define CURSOR_NONE 1
+#define CURSOR_PLAYFIELD 2
+
+// fundamental game speed values
+#define ONE_SECOND_DELAY 1000 // delay value for one second
+#define MENU_FRAME_DELAY 20 // frame delay in milliseconds
+#define GAME_FRAME_DELAY 20 // frame delay in milliseconds
+#define FFWD_FRAME_DELAY 10 // 200% speed for fast forward
+#define MIN_VSYNC_FRAME_DELAY 15 // minimum value for vsync to keep
+#define MAX_VSYNC_FRAME_DELAY 16 // maximum value for vsync to work
+#define FRAMES_PER_SECOND (ONE_SECOND_DELAY / GAME_FRAME_DELAY)
+#define FRAMES_PER_SECOND_SP 35
+
+// maximum playfield size supported by libgame functions
+#define MAX_PLAYFIELD_WIDTH 128
+#define MAX_PLAYFIELD_HEIGHT 128
+
+// maximum number of parallel players supported by libgame functions
+#define MAX_PLAYERS 4
+
+// maximum number of player names
+#define MAX_PLAYER_NAMES 12
+
+// maximum allowed length of player name
+#define MAX_PLAYER_NAME_LEN 10
+
+// maximum number of levels in a level set
+#define MAX_LEVELS 1000
+
+// maximum number of global animation and parts
+#define MAX_GLOBAL_ANIMS 32
+#define MAX_GLOBAL_ANIM_PARTS 32
+
+// minimum/maximum/default x/y grid size for virtual buttons
+#define MIN_GRID_XSIZE 3
+#define MIN_GRID_YSIZE 3
+#define MAX_GRID_XSIZE 32
+#define MAX_GRID_YSIZE 32
+#define GRID_REAL_WIDTH MAX(1, MAX(video.screen_width, \
+ video.screen_height))
+#define GRID_REAL_HEIGHT MAX(1, MIN(video.screen_width, \
+ video.screen_height))
+#define DEFAULT_GRID_XSIZE_0 18
+#define DEFAULT_GRID_YSIZE_0 MIN(MAX(MIN_GRID_YSIZE, \
+ DEFAULT_GRID_XSIZE_0 * \
+ GRID_REAL_HEIGHT / \
+ GRID_REAL_WIDTH), \
+ MAX_GRID_YSIZE)
+#define DEFAULT_GRID_XSIZE_1 13
+#define DEFAULT_GRID_YSIZE_1 MIN(MAX(MIN_GRID_YSIZE, \
+ DEFAULT_GRID_XSIZE_1 * \
+ GRID_REAL_WIDTH / \
+ GRID_REAL_HEIGHT), \
+ MAX_GRID_YSIZE)
+
+#define DEFAULT_GRID_XSIZE(n) ((n) == 0 ? DEFAULT_GRID_XSIZE_0 : \
+ DEFAULT_GRID_XSIZE_1)
+#define DEFAULT_GRID_YSIZE(n) ((n) == 0 ? DEFAULT_GRID_YSIZE_0 : \
+ DEFAULT_GRID_YSIZE_1)
+
+#define GRID_ACTIVE_NR() (video.screen_width > \
+ video.screen_height ? 0 : 1)
+
+// values for grid button characters for virtual buttons
+#define CHAR_GRID_BUTTON_NONE ' '
+#define CHAR_GRID_BUTTON_LEFT '<'
+#define CHAR_GRID_BUTTON_RIGHT '>'
+#define CHAR_GRID_BUTTON_UP '^'
+#define CHAR_GRID_BUTTON_DOWN 'v'
+#define CHAR_GRID_BUTTON_SNAP '1'
+#define CHAR_GRID_BUTTON_DROP '2'
+
+#define GET_ACTION_FROM_GRID_BUTTON(c) ((c) == CHAR_GRID_BUTTON_LEFT ? \
+ JOY_LEFT : \
+ (c) == CHAR_GRID_BUTTON_RIGHT ? \
+ JOY_RIGHT : \
+ (c) == CHAR_GRID_BUTTON_UP ? \
+ JOY_UP : \
+ (c) == CHAR_GRID_BUTTON_DOWN ? \
+ JOY_DOWN : \
+ (c) == CHAR_GRID_BUTTON_SNAP ? \
+ JOY_BUTTON_1 : \
+ (c) == CHAR_GRID_BUTTON_DROP ? \
+ JOY_BUTTON_2 : \
+ JOY_NO_ACTION)
+
+// maximum number of level sets in the level set history
+#define MAX_LEVELDIR_HISTORY 12
+
+// default name for empty highscore entry
+#define EMPTY_PLAYER_NAME "no name"
+
+// default name for unknown player names
+#define ANONYMOUS_NAME "anonymous"
+
+// default for other unknown names
+#define UNKNOWN_NAME "unknown"
+
+// default name for new levels
+#define NAMELESS_LEVEL_NAME "nameless level"
+
+// default text for non-existant artwork
+#define NOT_AVAILABLE "(not available)"
+
+// default value for undefined filename
+#define UNDEFINED_FILENAME "[NONE]"
+
+// default value for undefined levelset
+#define UNDEFINED_LEVELSET "[NONE]"
+
+// default value for undefined password
+#define UNDEFINED_PASSWORD "[undefined]"
+
+// default value for undefined parameter
+#define ARG_DEFAULT "[DEFAULT]"
+
+// default values for undefined configuration file parameters
+#define ARG_UNDEFINED "-1000000"
+#define ARG_UNDEFINED_VALUE (-1000000)
+
+// default value for off-screen positions
+#define POS_OFFSCREEN (-1000000)
+
+// definitions for game base path and sub-directories
+#ifndef BASE_PATH
+#define BASE_PATH "."
+#endif
+
+// directory names
+#define GRAPHICS_DIRECTORY "graphics"
+#define SOUNDS_DIRECTORY "sounds"
+#define MUSIC_DIRECTORY "music"
+#define LEVELS_DIRECTORY "levels"
+#define TAPES_DIRECTORY "tapes"
+#define SCORES_DIRECTORY "scores"
+#define DOCS_DIRECTORY "docs"
+#define CACHE_DIRECTORY "cache"
+#define CONF_DIRECTORY "conf"
+#define NETWORK_DIRECTORY "network"
+#define USERS_DIRECTORY "users"
+
+#define GFX_CLASSIC_SUBDIR "gfx_classic"
+#define SND_CLASSIC_SUBDIR "snd_classic"
+#define MUS_CLASSIC_SUBDIR "mus_classic"
+
+#define GFX_DEFAULT_SUBDIR (setup.internal.default_graphics_set)
+#define SND_DEFAULT_SUBDIR (setup.internal.default_sounds_set)
+#define MUS_DEFAULT_SUBDIR (setup.internal.default_music_set)
+
+#define GFX_FALLBACK_FILENAME (setup.internal.fallback_graphics_file)
+#define SND_FALLBACK_FILENAME (setup.internal.fallback_sounds_file)
+#define MUS_FALLBACK_FILENAME (setup.internal.fallback_music_file)
+
+#define DEFAULT_LEVELSET (setup.internal.default_level_series)
+
+// file names and filename extensions
+#define LEVELSETUP_DIRECTORY "levelsetup"
+#define SETUP_FILENAME "setup.conf"
+#define USERSETUP_FILENAME "usersetup.conf"
+#define AUTOSETUP_FILENAME "autosetup.conf"
+#define LEVELSETUP_FILENAME "levelsetup.conf"
+#define EDITORSETUP_FILENAME "editorsetup.conf"
+#define EDITORCASCADE_FILENAME "editorcascade.conf"
+#define HELPANIM_FILENAME "helpanim.conf"
+#define HELPTEXT_FILENAME "helptext.conf"
+#define LEVELINFO_FILENAME "levelinfo.conf"
+#define GRAPHICSINFO_FILENAME "graphicsinfo.conf"
+#define SOUNDSINFO_FILENAME "soundsinfo.conf"
+#define MUSICINFO_FILENAME "musicinfo.conf"
+#define ARTWORKINFO_CACHE_FILE "artworkinfo.cache"
+#define LEVELTEMPLATE_FILENAME "template.level"
+#define LEVELFILE_EXTENSION "level"
+#define TAPEFILE_EXTENSION "tape"
+#define SCOREFILE_EXTENSION "score"
+
+#define GAMECONTROLLER_BASENAME "gamecontrollerdb.txt"
+
+#define LOG_OUT_BASENAME "stdout.txt"
+#define LOG_ERR_BASENAME "stderr.txt"
+
+#define LOG_OUT_ID 0
+#define LOG_ERR_ID 1
+#define NUM_LOGS 2
+
+#define STRING_PARENT_DIRECTORY ".."
+#define STRING_TOP_DIRECTORY "/"
+
+#define CHAR_PATH_SEPARATOR_UNIX '/'
+#define CHAR_PATH_SEPARATOR_DOS '\\'
+
+#define STRING_PATH_SEPARATOR_UNIX "/"
+#define STRING_PATH_SEPARATOR_DOS "\\"
+
+#define STRING_NEWLINE_UNIX "\n"
+#define STRING_NEWLINE_DOS "\r\n"
+
+#if defined(PLATFORM_WIN32)
+#define CHAR_PATH_SEPARATOR CHAR_PATH_SEPARATOR_DOS
+#define STRING_PATH_SEPARATOR STRING_PATH_SEPARATOR_DOS
+#define STRING_NEWLINE STRING_NEWLINE_DOS
+#else
+#define CHAR_PATH_SEPARATOR CHAR_PATH_SEPARATOR_UNIX
+#define STRING_PATH_SEPARATOR STRING_PATH_SEPARATOR_UNIX
+#define STRING_NEWLINE STRING_NEWLINE_UNIX
+#endif
+
+
+// areas in bitmap PIX_DOOR
+// meaning in PIX_DB_DOOR: (3 PAGEs)
+// PAGEX1: 1. buffer for DOOR_1
+// PAGEX2: 2. buffer for DOOR_1
+// PAGEX3: buffer for animations
+
+// these values are hard-coded to be able to use them in initialization
+#define DOOR_GFX_PAGE_WIDTH 100 // should be set to "gfx.dxsize"
+#define DOOR_GFX_PAGE_HEIGHT 280 // should be set to "gfx.dysize"
+
+#define DOOR_GFX_PAGESIZE (DOOR_GFX_PAGE_WIDTH)
+#define DOOR_GFX_PAGEX1 (0 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX2 (1 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX3 (2 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX4 (3 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX5 (4 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX6 (5 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX7 (6 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEX8 (7 * DOOR_GFX_PAGESIZE)
+#define DOOR_GFX_PAGEY1 (0)
+#define DOOR_GFX_PAGEY2 (DOOR_GFX_PAGE_HEIGHT)
+
+
+// macros for version handling
+#define VERSION_PART_1(x) ((x) / 1000000)
+#define VERSION_PART_2(x) (((x) % 1000000) / 10000)
+#define VERSION_PART_3(x) (((x) % 10000) / 100)
+#define VERSION_PART_4(x) ((x) % 100)
+
+#define VERSION_SUPER(x) VERSION_PART_1(x)
+#define VERSION_MAJOR(x) VERSION_PART_2(x)
+#define VERSION_MINOR(x) VERSION_PART_3(x)
+#define VERSION_PATCH(x) VERSION_PART_4(x)
+#define VERSION_IDENT(a,b,c,d) ((a) * 1000000 + (b) * 10000 + (c) * 100 + (d))
+
+
+// macros for parent/child process identification
+#if defined(PLATFORM_UNIX)
+#define IS_PARENT_PROCESS() (audio.mixer_pid != getpid())
+#define IS_CHILD_PROCESS() (audio.mixer_pid == getpid())
+#define HAS_CHILD_PROCESS() (audio.mixer_pid > 0)
+#else
+#define IS_PARENT_PROCESS() TRUE
+#define IS_CHILD_PROCESS() FALSE
+#define HAS_CHILD_PROCESS() FALSE
+#endif
+
+
+// values for artwork type
+#define ARTWORK_TYPE_GRAPHICS 0
+#define ARTWORK_TYPE_SOUNDS 1
+#define ARTWORK_TYPE_MUSIC 2
+
+#define NUM_ARTWORK_TYPES 3
+
+
+// values for tree type (chosen to match artwork type)
+#define TREE_TYPE_UNDEFINED -1
+#define TREE_TYPE_GRAPHICS_DIR ARTWORK_TYPE_GRAPHICS
+#define TREE_TYPE_SOUNDS_DIR ARTWORK_TYPE_SOUNDS
+#define TREE_TYPE_MUSIC_DIR ARTWORK_TYPE_MUSIC
+#define TREE_TYPE_LEVEL_DIR 3
+#define TREE_TYPE_LEVEL_NR 4
+#define TREE_TYPE_PLAYER_NAME 5
+
+#define NUM_BASE_TREE_TYPES 4
+#define NUM_TREE_TYPES 6
+
+#define TREE_TYPE_IS_DIR(type) ((type) == TREE_TYPE_GRAPHICS_DIR || \
+ (type) == TREE_TYPE_SOUNDS_DIR || \
+ (type) == TREE_TYPE_MUSIC_DIR || \
+ (type) == TREE_TYPE_LEVEL_DIR)
+
+#define INFOTEXT_UNDEFINED ""
+#define INFOTEXT_GRAPHICS_DIR "Custom Graphics"
+#define INFOTEXT_SOUNDS_DIR "Custom Sounds"
+#define INFOTEXT_MUSIC_DIR "Custom Music"
+#define INFOTEXT_LEVEL_DIR "Level Sets"
+#define INFOTEXT_LEVEL_NR "Levels"
+#define INFOTEXT_PLAYER_NAME "Players & Teams"
+
+#define BACKLINK_TEXT_MAIN ".. (main menu)"
+#define BACKLINK_TEXT_SETUP ".. (setup menu)"
+#define BACKLINK_TEXT_PARENT ".. (parent directory)"
+
+#define TREE_INFOTEXT(t) ((t) == TREE_TYPE_PLAYER_NAME ? \
+ INFOTEXT_PLAYER_NAME : \
+ (t) == TREE_TYPE_LEVEL_NR ? \
+ INFOTEXT_LEVEL_NR : \
+ (t) == TREE_TYPE_LEVEL_DIR ? \
+ INFOTEXT_LEVEL_DIR : \
+ (t) == TREE_TYPE_GRAPHICS_DIR ? \
+ INFOTEXT_GRAPHICS_DIR : \
+ (t) == TREE_TYPE_SOUNDS_DIR ? \
+ INFOTEXT_SOUNDS_DIR : \
+ (t) == TREE_TYPE_MUSIC_DIR ? \
+ INFOTEXT_MUSIC_DIR : \
+ INFOTEXT_UNDEFINED)
+
+#define TREE_BACKLINK_TEXT(t) ((t) == TREE_TYPE_LEVEL_DIR ? \
+ BACKLINK_TEXT_MAIN : \
+ BACKLINK_TEXT_SETUP)
+
+#define TREE_USERDIR(t) ((t) == TREE_TYPE_LEVEL_DIR ? \
+ getUserLevelDir(NULL) : \
+ (t) == TREE_TYPE_GRAPHICS_DIR ? \
+ getUserGraphicsDir() : \
+ (t) == TREE_TYPE_SOUNDS_DIR ? \
+ getUserSoundsDir() : \
+ (t) == TREE_TYPE_MUSIC_DIR ? \
+ getUserMusicDir() : \
+ NULL)
+
+#define TREE_FIRST_NODE_PTR(t) ((t) == TREE_TYPE_LEVEL_DIR ? \
+ &leveldir_first : \
+ (t) == TREE_TYPE_GRAPHICS_DIR ? \
+ &artwork.gfx_first : \
+ (t) == TREE_TYPE_SOUNDS_DIR ? \
+ &artwork.snd_first : \
+ (t) == TREE_TYPE_MUSIC_DIR ? \
+ &artwork.mus_first : \
+ NULL)
+
+#define TREE_FIRST_NODE(t) ((t) == TREE_TYPE_LEVEL_DIR ? \
+ leveldir_first : \
+ (t) == TREE_TYPE_GRAPHICS_DIR ? \
+ artwork.gfx_first : \
+ (t) == TREE_TYPE_SOUNDS_DIR ? \
+ artwork.snd_first : \
+ (t) == TREE_TYPE_MUSIC_DIR ? \
+ artwork.mus_first : \
+ NULL)
+
+// values for artwork handling
+#define LEVELDIR_ARTWORK_SET_PTR(leveldir, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ &(leveldir)->graphics_set : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ &(leveldir)->sounds_set : \
+ &(leveldir)->music_set)
+
+#define LEVELDIR_ARTWORK_SET(leveldir, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (leveldir)->graphics_set : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (leveldir)->sounds_set : \
+ (leveldir)->music_set)
+
+#define LEVELDIR_ARTWORK_PATH_PTR(leveldir, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ &(leveldir)->graphics_path : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ &(leveldir)->sounds_path : \
+ &(leveldir)->music_path)
+
+#define LEVELDIR_ARTWORK_PATH(leveldir, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (leveldir)->graphics_path : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (leveldir)->sounds_path : \
+ (leveldir)->music_path)
+
+#define SETUP_ARTWORK_SET(setup, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (setup).graphics_set : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (setup).sounds_set : \
+ (setup).music_set)
+
+#define SETUP_OVERRIDE_ARTWORK(setup, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (setup).override_level_graphics : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (setup).override_level_sounds : \
+ (setup).override_level_music)
+
+#define GFX_OVERRIDE_ARTWORK(type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ gfx.override_level_graphics : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ gfx.override_level_sounds : \
+ gfx.override_level_music)
+
+#define ARTWORK_FIRST_NODE(artwork, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (artwork).gfx_first : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (artwork).snd_first : \
+ (artwork).mus_first)
+
+#define ARTWORK_CURRENT_PTR(artwork, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ &(artwork).gfx_current : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ &(artwork).snd_current : \
+ &(artwork).mus_current)
+
+#define ARTWORK_CURRENT(artwork, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (artwork).gfx_current : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (artwork).snd_current : \
+ (artwork).mus_current)
+
+#define ARTWORK_CURRENT_IDENTIFIER_PTR(artwork, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ &(artwork).gfx_current_identifier : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ &(artwork).snd_current_identifier : \
+ &(artwork).mus_current_identifier)
+
+#define ARTWORK_CURRENT_IDENTIFIER(artwork, type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ (artwork).gfx_current_identifier : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ (artwork).snd_current_identifier : \
+ (artwork).mus_current_identifier)
+
+#define ARTWORKINFO_FILENAME(type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ GRAPHICSINFO_FILENAME : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ SOUNDSINFO_FILENAME : \
+ (type) == ARTWORK_TYPE_MUSIC ? \
+ MUSICINFO_FILENAME : "")
+
+#define ARTWORK_DIRECTORY(type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ GRAPHICS_DIRECTORY : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ SOUNDS_DIRECTORY : \
+ (type) == ARTWORK_TYPE_MUSIC ? \
+ MUSIC_DIRECTORY : "")
+
+#define OPTIONS_ARTWORK_DIRECTORY(type) \
+ ((type) == ARTWORK_TYPE_GRAPHICS ? \
+ options.graphics_directory : \
+ (type) == ARTWORK_TYPE_SOUNDS ? \
+ options.sounds_directory : \
+ (type) == ARTWORK_TYPE_MUSIC ? \
+ options.music_directory : "")