Removed a temporary file I can't even remember what I was doing to make it worth... master
authorMartin Read <mpread@chiark.greenend.org.uk>
Sat, 5 Apr 2014 17:36:34 +0000 (18:36 +0100)
committerMartin Read <mpread@chiark.greenend.org.uk>
Sat, 5 Apr 2014 17:36:34 +0000 (18:36 +0100)
map.cc.old [deleted file]

diff --git a/map.cc.old b/map.cc.old
deleted file mode 100644 (file)
index de25b79..0000000
+++ /dev/null
@@ -1,835 +0,0 @@
-/*! \file map.cc
- *  \brief Map generation and population
- */
-
-/* Copyright 2005-2014 Martin Read
- * 
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "victrix-abyssi.hh"
-#include "objects.hh"
-#include "monsters.hh"
-#include "mapgen.hh"
-
-#include <string.h>
-Level lvl;
-int depth;
-
-void drop_all_chunks(Level *l)
-{
-    int i;
-    int j;
-    if (l->chunks)
-    {
-        for (i = 0; i < l->chunks_high; ++i)
-        {
-            for (j = 0; j < l->chunks_wide; ++j)
-            {
-                if (l->chunks[i][j])
-                {
-                    delete l->chunks[i][j];
-                }
-                l->chunks[i][j] = nullptr;
-            }
-            delete[] l->chunks[i];
-            l->chunks[i] = nullptr;
-        }
-        delete[] l->chunks;
-        l->chunks = nullptr;
-    }
-}
-
-Chunk::Chunk(Terrain t)
-{
-    int k, m;
-    for (k = 0; k < CHUNK_EDGE; ++k)
-    {
-        for (m = 0; m < CHUNK_EDGE; ++m)
-        {
-            objs[k][m] = NO_OBJ;
-            mons[k][m] = NO_MON;
-            terrain[k][m] = t;
-            flags[k][m] = 0;
-            region_number[k][m] = NO_REGION;
-        }
-    }
-}
-
-void initialize_chunks(Level *l, int height, int width, bool dense)
-{
-    Chunk ***new_chunk_grid;
-    Chunk **new_chunk_row;
-    Chunk *new_chunk;
-    int i;
-    int j;
-    drop_all_chunks(l);
-    l->origin_off = Stationary;
-    l->chunks_high = height;
-    l->chunks_wide = width;
-    new_chunk_grid = new Chunk ** [height];
-    for (i = 0; i < height; ++i)
-    {
-        new_chunk_row = new Chunk * [width];
-        for (j = 0; j < width; ++j)
-        {
-            new_chunk_row[j] = new_chunk = (dense ? new Chunk(l->dead_space) : nullptr);
-        }
-        new_chunk_grid[i] = new_chunk_row;
-    }
-    l->chunks = new_chunk_grid;
-}
-
-void Level::vivify(Coord c)
-{
-    Coord rc = c + origin_off;
-    while (rc.y < 0)
-    {
-        grow(North);
-        rc = c + origin_off;
-    }
-    while (rc.y > (chunks_high << CHUNK_SHIFT))
-    {
-        grow(South);
-    }
-    while (rc.x < 0)
-    {
-        grow(West);
-        rc = c + origin_off;
-    }
-    while (rc.x > (chunks_wide << CHUNK_SHIFT))
-    {
-        grow(East);
-    }
-    if (!chunks[rc.y >> CHUNK_SHIFT][rc.x >> CHUNK_SHIFT])
-    {
-        chunks[rc.y >> CHUNK_SHIFT][rc.x >> CHUNK_SHIFT] = new Chunk(dead_space);
-    }
-}
-
-void Level::grow(Offset o, bool dense)
-{
-    Chunk ***new_chunk_grid;
-    Chunk **new_chunk_row;
-    int i;
-    int j;
-    if (o.y < 0)
-    {
-        int i;
-        origin_off.y += CHUNK_EDGE;
-        ++chunks_high;
-        new_chunk_grid = new Chunk **[chunks_high];
-        for (i = 0; i < (chunks_high - 1); ++i)
-        {
-            new_chunk_grid[i + 1] = chunks[i];
-        }
-        new_chunk_grid[0] = new_chunk_row = new Chunk *[chunks_wide];
-        for (i = 0; i < chunks_wide; ++i)
-        {
-            new_chunk_row[i] = dense ? new Chunk(dead_space) : nullptr;
-        }
-        delete[] chunks;
-        chunks = new_chunk_grid;
-    }
-    else if (o.y > 0)
-    {
-        ++chunks_high;
-        new_chunk_grid = new Chunk **[chunks_high];
-        for (i = 0; i < (chunks_high - 1); ++i)
-        {
-            new_chunk_grid[i] = chunks[i];
-        }
-        new_chunk_grid[chunks_high - 1] = new_chunk_row = new Chunk *[chunks_wide];
-        for (i = 0; i < chunks_wide; ++i)
-        {
-            new_chunk_row[i] = dense ? new Chunk(dead_space) : nullptr;
-        }
-        delete[] chunks;
-        chunks = new_chunk_grid;
-    }
-    if (o.x < 0)
-    {
-        ++chunks_wide;
-        origin_off.x += CHUNK_EDGE;
-        for (i = 0; i < chunks_high; ++i)
-        {
-            new_chunk_row = new Chunk *[chunks_wide];
-            for (j = 0; j < chunks_wide - 1; ++j)
-            {
-                new_chunk_row[j + 1] = chunks[i][j];
-            }
-            new_chunk_row[0] = dense ? new Chunk(dead_space) : nullptr;
-            delete[] chunks[i];
-            chunks[i] = new_chunk_row;
-        }
-    }
-    else if (o.x > 0)
-    {
-        ++chunks_wide;
-        for (i = 0; i < chunks_high; ++i)
-        {
-            new_chunk_row = new Chunk *[chunks_wide];
-            for (j = 0; j < chunks_wide - 1; ++j)
-            {
-                new_chunk_row[j] = chunks[i][j];
-            }
-            new_chunk_row[chunks_wide - 1] = dense ? new Chunk(dead_space) : nullptr;
-            delete[] chunks[i];
-            chunks[i] = new_chunk_row;
-        }
-    }
-}
-
-/*! \brief Find a random point on the level
- *
- * \param margin Width of the "dead" space along each edge in which the point cannot appear
- */
-Coord Level::random_point(int margin) const
-{
-    Coord tl = { margin, margin };
-    Coord br = { GUIDE_EDGE_SIZE - (margin + 1), GUIDE_EDGE_SIZE - (margin + 1) };
-    return inc_boxed(tl, br);
-}
-
-int Level::add_stairs_at(Coord c, Terrain t, Level_key l)
-{
-    Stair_detail sd = { c, t, l };
-    if (!(terrain_props[t].flags & 
-          (TFLAG_ascend | TFLAG_portal | TFLAG_descend)))
-    {
-        return NO_STAIRS;
-    }
-    set_terrain_at(c, t);
-    stairs.push_back(sd);
-    return stairs.size() - 1;
-}
-
-Level_key const No_level = { 65535, -32768 };
-
-Stair_detail const Bad_stairs = { Nowhere, FLOOR, No_level };
-Stair_detail Level::find_stairs(Coord pos) const
-{
-    for (auto iter = stairs.begin(); iter != stairs.end(); ++iter)
-    {
-        if (iter->pos == pos)
-        {
-            return *iter;
-        }
-    }
-    return Bad_stairs;
-}
-
-int Level::find_stairs(Terrain t, std::vector<Stair_detail> *dest) const
-{
-    int count = 0;
-    for (auto iter = stairs.begin(); iter != stairs.end(); ++iter)
-    {
-        if (iter->t == t)
-        {
-            dest->push_back(*iter);
-            ++count;
-        }
-    }
-    return count;
-}
-
-int Level::find_stairs(Level_key from, std::vector<Stair_detail> *dest) const
-{
-    int count = 0;
-    for (auto iter = lvl.stairs.begin(); iter != lvl.stairs.end(); ++iter)
-    {
-        if (iter->destination == from)
-        {
-            dest->push_back(*iter);
-            ++count;
-        }
-    }
-    return count;
-}
-
-void leave_level(void)
-{
-    int i;
-    for (i = 0; i < 100; i++)
-    {
-        /* Throw away each monster */
-        monsters[i].used = false;
-        /* and each object not carried by the player */
-        if (!objects[i].with_you)
-        {
-            objects[i].used = false;
-        }
-    }
-    depth++;
-}
-
-void make_new_level(void)
-{
-    build_level();
-    populate_level();
-    inject_player(lvl.self.naive_prev());
-    look_around_you();
-    notify_change_of_depth();
-}
-
-/*! \brief Random walk which grows the level
- *
- * This version of run_random_walk will extend the level boundaries instead
- * of rejecting out-of-bounds coordinates.
- */
-Coord run_random_walk(Coord oc, rwalk_mod_funcptr func,
-                      void const *priv_ptr, int cells)
-{
-    int i;
-    Coord c = oc;
-    int bailout = 10000;
-
-    func(c, priv_ptr);
-    for (i = 0; (i < cells) && (bailout > 0); --bailout)
-    {
-        oc = c;
-        if (zero_die(2))
-        {
-            c.y += (zero_die(2) ? -1 : 1);
-            c.y = std::min(lvl.max_y() - 2, std::max(c.y, lvl.min_y() + 2));
-        }
-        else
-        {
-            c.x += (zero_die(2) ? -1 : 1);
-            c.x = std::min(lvl.max_x() - 2, std::max(c.x, lvl.min_x() + 2));
-        }
-        switch (func(c, priv_ptr))
-        {
-        case 0:
-            /* nothing changed */
-            break;
-        case 1:
-            /* changed normally */
-            ++i;
-            break;
-        case 2:
-            /* reject! */
-            c = oc;
-            break;
-        }
-    }
-    if (bailout < 1)
-    {
-        debug_excavation_bailout();
-    }
-    return c;
-}
-
-/*! \brief Random walk which grows the level
- *
- * This version of run_random_walk will extend the level boundaries instead
- * of rejecting out-of-bounds coordinates.
- */
-Coord run_random_walk_unbounded(Coord oc, rwalk_mod_funcptr func,
-                                void const *priv_ptr, int cells)
-{
-    int i;
-    Coord c = oc;
-    int bailout = 10000;
-
-    func(c, priv_ptr);
-    for (i = 0; (i < cells) && (bailout > 0); --bailout)
-    {
-        oc = c;
-        if (zero_die(2))
-        {
-            c.y += (zero_die(2) ? -1 : 1);
-        }
-        else
-        {
-            c.x += (zero_die(2) ? -1 : 1);
-        }
-        if (c.y <= lvl.min_y())
-        {
-            lvl.grow(North, true);
-        }
-        if (c.y >= lvl.max_y())
-        {
-            lvl.grow(South, true);
-        }
-        if (c.x <= lvl.min_x())
-        {
-            lvl.grow(West, true);
-        }
-        if (c.x >= lvl.max_x())
-        {
-            lvl.grow(East, true);
-        }
-        switch (func(c, priv_ptr))
-        {
-        case 0:
-            /* nothing changed */
-            break;
-        case 1:
-            /* changed normally */
-            ++i;
-            break;
-        case 2:
-            /* reject! */
-            c = oc;
-            break;
-        }
-    }
-    if (bailout < 1)
-    {
-        debug_excavation_bailout();
-    }
-    return c;
-}
-
-/*! \brief Entry point for level generation.
- *
- *  \todo Maybe implement support for Lua-based level generators.
- */
-void build_level(void)
-{
-    int theme_roll;
-    lvl.self.depth = (int16_t) depth;
-    lvl.self.dungeon = 0;
-    lvl.stairs.clear();
-    rng.extract_serialization(saved_state_buffer, saved_state_size);
-    theme_roll = zero_die(depth + 50);
-    if (!zero_die(4))
-    {
-        lvl.layout = LAYOUT_CAVE_INTRUSIONS;
-    }
-    else if ((depth > 1) && !zero_die(6))
-    {
-        lvl.layout = LAYOUT_CAVE_SHRINE;
-    }
-    else
-    {
-        lvl.layout = LAYOUT_CLASSIC_CAVE;
-    }
-    if ((theme_roll < 50) || (depth < 10))
-    {
-        lvl.theme = THEME_NORMAL; /* no restrictions */
-    }
-    else if (theme_roll < 60)
-    {
-        lvl.theme = THEME_UNDEAD;
-    }
-    else if (theme_roll < 80)
-    {
-        lvl.theme = THEME_DRAGONS;
-    }
-    else if (theme_roll < 90)
-    {
-        lvl.theme = THEME_DEMONS;
-    }
-    switch (lvl.layout)
-    {
-    case LAYOUT_CAVE_SHRINE:
-        build_level_shrine();
-        break;
-    case LAYOUT_CAVE_INTRUSIONS:
-        build_level_intrusions();
-        break;
-    case LAYOUT_DUNGEONBASH:
-        build_level_dungeonbash();
-        break;
-    case LAYOUT_CLASSIC_CAVE:
-        build_level_cave();
-        break;
-    }
-}
-
-/*! \brief Build a dungeonbash-style rooms-and-corridors level */
-void build_level_dungeonbash()
-{
-    int chy;
-    int chx;
-    /* We know we're going to use all nine chunks, so create them
-     * immediately. */
-    initialize_chunks(&lvl, GUIDE_EDGE_CHUNKS, GUIDE_EDGE_CHUNKS, true);
-    /* One room per chunk. */
-    for (chy = 0; chy < lvl.chunks_high; ++chy)
-    {
-        for (chx = 0; chx < lvl.chunks_wide; ++ chx)
-        {
-            /* Smallest allowed room has a 2x2 interior. */
-            Offset room_size = { MIN_ROOM_EDGE + zero_die(5), MIN_ROOM_EDGE + zero_die(5) };
-            /* Each dimension has a 1-in-3 chance to get another boost */
-            if (!zero_die(3))
-            {
-                room_size.y += zero_die(5);
-            }
-            if (!zero_die(3))
-            {
-                room_size.x += zero_die(5);
-            }
-        }
-    }
-}
-
-/*! \brief Excavation function for use with random walks */
-int excavation_write(Coord c, void const *data)
-{
-    int const *data_as_ints = (int const *) data;
-    int const *overwrite = data_as_ints + 2;
-    int newterr = data_as_ints[1];
-    int j;
-    if (lvl.flags_at(c) & MAPFLAG_HARDWALL)
-    {
-        /* Don't bite into hardened walls, but don't waste a step on
-         * them either. */
-        return 2;
-    }
-    for (j = 0; j < data_as_ints[0]; ++j)
-    {
-        if (lvl.terrain_at(c) == overwrite[j])
-        {
-            lvl.set_terrain_at(c, (Terrain) newterr);
-            return 1;
-        }
-    }
-    return 0;
-}
-
-/*! \brief "Intrusion" function for use with random walks */
-int intrusion_write(Coord c, void const *data)
-{
-    Terrain const *tptr = (Terrain const *) data;
-    if ((lvl.terrain_at(c) != WALL) || (lvl.flags_at(c) & MAPFLAG_HARDWALL))
-    {
-        return 0;
-    }
-    /* Don't intrude too closely on the centre of the level */
-    if ((c.y > ((GUIDE_EDGE_SIZE / 2) - 4)) && (c.y < ((GUIDE_EDGE_SIZE / 2) - 4)))
-    {
-        return 2;
-    }
-    if ((c.x > ((GUIDE_EDGE_SIZE / 2) - 4)) && (c.x < ((GUIDE_EDGE_SIZE / 2) - 4)))
-    {
-        return 2;
-    }
-    if (tptr)
-    {
-        lvl.set_terrain_at(c, *tptr);
-    }
-    lvl.set_flags_at(c, MAPFLAG_HARDWALL);
-    return 1;
-}
-
-/*! \brief Do a random walk laying down an exclusion area */
-void place_random_intrusion(Terrain new_wall)
-{
-    Coord c;
-    int intrusion_size = inc_flat(27, 54);
-    do
-    {
-        c.x = zero_die(2) ? inc_flat(1, GUIDE_EDGE_SIZE / 3) : inc_flat((2 * GUIDE_EDGE_SIZE) / 3, GUIDE_EDGE_SIZE - 2);
-        c.y = zero_die(2) ? inc_flat(1, GUIDE_EDGE_SIZE / 3) : inc_flat((2 * GUIDE_EDGE_SIZE) / 3, GUIDE_EDGE_SIZE - 2);
-    } while (lvl.flags_at(c) & MAPFLAG_HARDWALL);
-    run_random_walk(c, intrusion_write, &new_wall, intrusion_size);
-}
-
-/*! \brief Get a valid square to generate a monster on */
-Pass_fail get_levgen_mon_floor(Coord *c)
-{
-    int cell_try;
-    Coord t;
-    for (cell_try = 0; cell_try < 200; cell_try++)
-    {
-        t = lvl.random_point(1);
-        if ((lvl.terrain_at(t) != FLOOR) || (lvl.mon_at(t) != NO_MON))
-        {
-            t = Nowhere;
-            continue;
-        }
-        break;
-    }
-    if (t == Nowhere)
-    {
-        return You_fail;
-    }
-    *c = t;
-    return You_pass;
-}
-
-/*! \brief Populate the level! */
-void populate_level(void)
-{
-    int i;
-    Pass_fail pf;
-    Coord c;
-    int ic;
-    /* Generate some random monsters */
-    for (i = 0; i < 10; i++)
-    {
-        pf = get_levgen_mon_floor(&c);
-        if (pf == You_fail)
-        {
-            continue;
-        }
-        create_mon(NO_PMON, c);
-    }
-    ic = 3 + depth;
-    if (ic > 40)
-    {
-        /* Never create more than 40 items. */
-        ic = 40;
-    }
-    /* Generate some random treasure */
-    for (i = 0; i < ic; i++)
-    {
-        pf = get_levgen_mon_floor(&c);
-        if (pf == You_fail)
-        {
-            continue;
-        }
-        create_obj(NO_POBJ, 1, 0, c);
-    }
-}
-
-/*! \brief Inject the player into the level based on where they arrived from */
-void inject_player(Level_key from)
-{
-    /* For now we are allowing only one linkage between levels */ 
-    Coord c;
-    std::vector<Stair_detail> stair_list;
-    int i = lvl.find_stairs(from, &stair_list);
-    if (i != 0)
-    {
-        c = stair_list[0].pos;
-    }
-    else
-    {
-        fprintf(stderr, "Couldn't find any stairs!\n");
-        abort();
-    }
-    u.pos = c;
-    reloc_player(u.pos);
-}
-
-/*! \brief Look around the player */
-void look_around_you(void)
-{
-    compute_fov();
-    notify_fov();
-}
-
-/*! \brief Description of terrain types */
-Terrain_props terrain_props[NUM_TERRAINS] = 
-{
-    { "cave wall", '#', "█", Gcol_brown, TFLAG_opaque | TFLAG_block_beings | TFLAG_block_missile },
-    { "masonry wall", '#', "█", Gcol_l_grey, TFLAG_opaque | TFLAG_block_beings | TFLAG_block_missile },
-    { "amethyst wall", '#', "█", Gcol_purple, TFLAG_opaque | TFLAG_block_beings | TFLAG_block_missile },
-    { "iron wall", '#', "█", Gcol_purple, TFLAG_opaque | TFLAG_block_beings | TFLAG_block_missile },
-    { "skin wall", '#', "█", Gcol_l_purple, TFLAG_opaque | TFLAG_block_beings | TFLAG_block_missile },
-    { "bone wall", '#', "█", Gcol_white, TFLAG_opaque | TFLAG_block_beings | TFLAG_block_missile },
-    { "door", '+', "+", Gcol_l_grey, TFLAG_opaque | TFLAG_block_missile },
-    { "floor", '.', "·", Gcol_l_grey, TFLAG_floor },
-    { "amethyst floor", '.', "·", Gcol_purple, TFLAG_floor },
-    { "iron floor", '.', "·", Gcol_iron, TFLAG_floor },
-    { "skin floor", '.', "·", Gcol_l_purple, TFLAG_floor },
-    { "bone floor", '.', "·", Gcol_white, TFLAG_floor },
-    { "altar", '_', "_", Gcol_l_grey, 0 },
-    { "upward stairs", '<', "<", Gcol_l_grey, TFLAG_ascend },
-    { "downward stairs", '>', ">", Gcol_l_grey, TFLAG_descend },
-    { "lava", '}', "≈", Gcol_red, TFLAG_fire_hazard },
-    { "water", '}', "≈", Gcol_blue, TFLAG_drown_hazard },
-};
-
-/*! \brief self-explanatory */
-bool terrain_is_opaque(Terrain terr)
-{
-    return terrain_props[terr].flags & TFLAG_opaque;
-}
-
-/*! \brief self-explanatory */
-bool terrain_blocks_beings(Terrain terr)
-{
-    return terrain_props[terr].flags & TFLAG_block_beings;
-}
-
-/*! \brief self-explanatory */
-bool terrain_blocks_missiles(Terrain terr)
-{
-    return terrain_props[terr].flags & TFLAG_block_missile;
-}
-
-/*! \brief Read a Chunk from a FILE.
- *
- *  Yes, I know "throw(errno)" is tacky and stupid, but it achieves the
- *  desired result: the save is obviously garbage, so there's no point
- *  in finishing loading it.
- */
-void deserialize_chunk(FILE *fp, Chunk *c)
-{
-    static uint32_t deserializable_terrain[CHUNK_EDGE][CHUNK_EDGE];
-    static uint32_t deserializable_flags[CHUNK_EDGE][CHUNK_EDGE];
-    static uint32_t deserializable_regions[CHUNK_EDGE][CHUNK_EDGE];
-    int i;
-    int j;
-    wrapped_fread(deserializable_terrain, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
-    wrapped_fread(deserializable_flags, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
-    wrapped_fread(deserializable_regions, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
-    for (i = 0; i < CHUNK_EDGE; ++i)
-    {
-        for (j = 0; j < CHUNK_EDGE; ++j)
-        {
-            c->terrain[i][j] = (Terrain) ntohl(deserializable_terrain[i][j]);
-            c->flags[i][j] = ntohl(deserializable_flags[i][j]);
-            c->region_number[i][j] = ntohl(deserializable_regions[i][j]);
-            /* objs and mons will get accurately set once we've loaded the
-             * objs and mons. */
-            c->objs[i][j] = NO_OBJ;
-            c->mons[i][j] = NO_MON;
-        }
-    }
-}
-
-/*! \brief Write a Chunk out to a FILE.  */
-void serialize_chunk(FILE *fp, Chunk const *c)
-{
-    static uint32_t serializable_terrain[CHUNK_EDGE][CHUNK_EDGE];
-    static uint32_t serializable_flags[CHUNK_EDGE][CHUNK_EDGE];
-    static uint32_t serializable_regions[CHUNK_EDGE][CHUNK_EDGE];
-    int i;
-    int j;
-    for (i = 0; i < CHUNK_EDGE; ++i)
-    {
-        for (j = 0; j < CHUNK_EDGE; ++j)
-        {
-            serializable_terrain[i][j] = htonl(c->terrain[i][j]);
-            serializable_flags[i][j] = htonl(c->flags[i][j]);
-            serializable_regions[i][j] = htonl(c->region_number[i][j]);
-        }
-    }
-    fwrite(serializable_terrain, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
-    fwrite(serializable_flags, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
-    fwrite(serializable_regions, 4, CHUNK_EDGE * CHUNK_EDGE, fp);
-}
-
-/*! \brief Serialize a Level */
-void serialize_level(FILE *fp, Level const *l)
-{
-    uint32_t tmp;
-    uint32_t tmp_pair[2];
-    uint16_t tmp_shorts[2];
-    int i;
-    int j;
-    tmp_shorts[0] = htons(l->self.dungeon);
-    tmp_shorts[1] = htons(l->self.depth);
-    fwrite(tmp_shorts, sizeof tmp_shorts[0], 2, fp);
-    tmp_pair[0] = htonl(l->origin_off.y);
-    tmp_pair[1] = htonl(l->origin_off.x);
-    fwrite(tmp_pair, sizeof tmp_pair[0], 2, fp);
-    tmp = htonl(l->dead_space);
-    fwrite(&tmp, sizeof tmp, 1, fp);
-    tmp = htonl(l->theme);
-    fwrite(&tmp, sizeof tmp, 1, fp);
-    tmp = htonl(l->layout);
-    fwrite(&tmp, sizeof tmp, 1, fp);
-    tmp = htonl(l->chunks_high);
-    fwrite(&tmp, sizeof tmp, 1, fp);
-    tmp = htonl(l->chunks_wide);
-    fwrite(&tmp, sizeof tmp, 1, fp);
-    for (i = 0; i < l->chunks_high; ++i)
-    {
-        tmp_pair[0] = htonl(i);
-        for (j = 0; j < l->chunks_wide; ++j)
-        {
-            if (l->chunks[i][j])
-            {
-                tmp_pair[1] = htonl(j);
-                fwrite(tmp_pair, sizeof tmp_pair[0], 2, fp);
-                serialize_chunk(fp, l->chunks[i][j]);
-            }
-        }
-    }
-    tmp_pair[0] = tmp_pair[1] = ~0u;
-    fwrite(tmp_pair, sizeof tmp_pair[0], 2, fp);
-}
-
-/*! \brief Deserialize a Level
- *
- * \todo Throw an exception if the level is malformed e.g. OOB chunk indices.
- */
-void deserialize_level(FILE *fp, Level *l)
-{
-    uint32_t tmp;
-    uint32_t tmp_pair[2];
-    uint16_t tmp_shorts[2];
-    uint32_t i;
-    uint32_t j;
-    wrapped_fread(tmp_shorts, sizeof tmp_shorts[0], 2, fp);
-    l->self.dungeon = ntohs(tmp_shorts[0]);
-    l->self.depth = (int16_t) ntohs(tmp_shorts[1]);
-    wrapped_fread(tmp_pair, sizeof tmp_pair[0], 2, fp);
-    l->origin_off.y = (int) ntohl(tmp_pair[0]);
-    l->origin_off.x = (int) ntohl(tmp_pair[1]);
-    wrapped_fread(&tmp, sizeof tmp, 1, fp);
-    l->dead_space = Terrain(ntohl(tmp));
-    wrapped_fread(&tmp, sizeof tmp, 1, fp);
-    l->theme = level_theme(ntohl(tmp));
-    wrapped_fread(&tmp, sizeof tmp, 1, fp);
-    l->layout = level_layout(ntohl(tmp));
-    wrapped_fread(&tmp, sizeof tmp, 1, fp);
-    l->chunks_high = ntohl(tmp);
-    wrapped_fread(&tmp, sizeof tmp, 1, fp);
-    l->chunks_wide = ntohl(tmp);
-    initialize_chunks(l, l->chunks_high, l->chunks_wide, false);
-    do
-    {
-        wrapped_fread(&tmp_pair, sizeof tmp_pair[0], 2, fp);
-        i = ntohl(tmp_pair[0]);
-        j = ntohl(tmp_pair[1]);
-        if (i == ~0u)
-        {
-            break;
-        }
-        l->chunks[i][j] = new Chunk(l->dead_space);
-        deserialize_chunk(fp, l->chunks[i][j]);
-    }
-    while (1);
-}
-
-uint32_t rotate_connection_mask(uint32_t val, int clockwise_steps)
-{
-    clockwise_steps &= 0x3;
-    return ((val << clockwise_steps) | ((val & 0xf) >> (4 - clockwise_steps))) & 0xf;
-}
-
-void level_cleanup(void)
-{
-    int i;
-    for (i = 0; i < MONSTERS_IN_PLAY; ++i)
-    {
-        monsters[i].used = false;
-    }
-    for (i = 0; i < OBJECTS_IN_PLAY; ++i)
-    {
-        objects[i].used = false;
-        objects[i].with_you = false;
-    }
-    drop_all_chunks(&lvl);
-}
-
-/* map.cc */
-// vim:cindent:ts=8:sw=4:expandtab