Hey all. The code I've made for this project is massive, convoluted and horrifying. Of course I'll share it on request! =-D Basically this:

2D Tile Based Screen - fine.
Scrolling 2D Tile Based Screen - fine.
The problems start with the dynamically generated zones part:

Exerpt from world.h:
Code:
struct TileT
{
    int ID;
    int Type;
} Tile;

typedef std::vector<TileT> Row;
typedef std::vector<Row> Zone;
typedef std::map<std::string, Zone> AreaMap;
I construct a zone 'tag' based on the camera's World Coordinates (These could be anything (unsigned int, will switch to unsigned long if needed) so negative values are fine. Initially, if I delete all the maps in the /maps/ directory - the game takes the coordinates 0,0 to start.

example of a zone function:
Code:
std::string CoordsToZoneTag(mrt::Coords2i Coords, int AreaID = 1)
{
    // Generates and returns a string holding the zone tag
    // of the zone file containing the coordinates provided.
    int x = Coords.x;
    int y = Coords.y;

    char SignX = x > 0 ? 'P' : 'N';
    char SignY = y > 0 ? 'P' : 'N';

    int ax = abs(Coords.x);
    int ay = abs(Coords.y);

    std::stringstream zn;

    zn << SignX << (ax < 100 ? "0" : "") << (ax < 10 ? "0" : "") << ax;
    zn << SignY << (ay < 100 ? "0" : "") << (ay < 10 ? "0" : "") << ay;
    zn << "A"   << (AreaID  < 100 ? "0" : "") << (AreaID  < 10 ? "0" : "") << AreaID;

    return zn.str();;
}
It figures the tags for the 4 zones which may be on screen in part or in whole.
These will be like N001N001A001 for a screen 1 zone to the north and the west from the origin... moving on.

So then it checks the /maps/ directory for the 4 tags (after they've been changed to file paths). If it doesn't find one of them, it takes a moment to generate it with the default zero value for TileID and Type (so, basically like 001:000 would be a grass tile that's passable (ie: Not a wall, or river or w/e)

I don't think it's important, but here's the functions that generate the file, for example...

writing a zone file...
Code:
bool CreateZone(int zx, int zy)
{
    // Create a zone based on it's ZoneCoords.
    const std::string ZoneFileName = GenZonePath(zx, zy);

    std::ofstream outfile;
    outfile.open(ZoneFileName.c_str());
    if (!outfile) {
        std::cout << "World::CreatZone: Couldn't open zone file for creation!";
        return false;
    }
    outfile << "# ZoneFile Version 0.5" << std::endl;
    outfile << "# Area Label \"" << std::string(ZoneFileName).substr(5, 11) << "\"." << std::endl;
    outfile << "# System generated zone file: " << ZoneFileName << "\t\t(" << zx << ", " << zy << ")" << std::endl;

    // Text Files must be written left to right
    for (int y = 0; y < TILE_ROWS_Y_H; ++y)
    {
        for(int x = 0; x < TILE_COLS_X_W; ++x)
        {
            // Write the ID for tile (1,0) and Walkable Type (000)
            outfile << "001" << ":" << "000";
            if (x < TILE_COLS_X_W - 1) outfile << ": ";
        }
        outfile << std::endl;
    }
    outfile.close();
    return true;
}
Anyhow, in the actual processing of the movement, I move the character and if he gets too far from the camera's position, it scrolls to him, setting up a jerky kind of following. World fine for my early stage of developement.

The problem is efficiently reading the four zone object's from memory, and rending them in a timely fashion. My problem, I THINK is how I get the zones in and out of memory.

In the beginning, when the engine first loads, it will scour the maps/ directory and load ALL the *.zon files into typedef std::map<std::string, Zone> AreaMap and then during the games main loop, it will derive the 4 needed zone 'tags' from the area, and find them in the map - retrieve the zone object they are associated with and render it.

My best effort so far rending one screen with no dynamic shennannigans, was that I could render the screen nearly 300 times a second. After the dynamic hub bub was added and believe me, it was hacked in.... I'm so undisciplined. Anyhow, the fps dropped to 3 or 4, and it was horrid.

I'm re-writing now from scratch and will hopefully do better this time. The idea is that any individual tile can be modified in memory at any time, (any tile currently displayed, you don't want to edit tiles you can't see) and then with a push of F2, the entire AREA structure in memory is run through, tags are read from the zone files, or the Area map itself, zones that have changed since last load are saved again, over-writing the *.zon file, etc.

I've got all the pieces, but it's a mess.

My problem I think comes from the World Class loading it's zones into the Area Map, which I think works fine. But then maintaining a 'drawable' structre. A structure telling us what zones need to be draw in the current loop.

The angle I am working at the moment is a table of Zone Pointers, like this:
struct ZoneTableT
Code:
{
    ZoneTableT() : NW(nullptr), NE(nullptr), SW(nullptr), SE(nullptr)  {};
    Zone *NW;
    Zone *NE;
    Zone *SW;
    Zone *SE;

} ZoneTable;
In theory, this allowed me to move from a Map to a simple vector of zones - it's tanked horribly however with segfaults galore.

Code like this is not helping:
Code:
void UpdateZoneTable(Area& area, ZoneTableT& ZT, int x, int y)
{
    // Update the pointer of the ZoneTable
    // with reguard to the "World" vector of Zones.
    // Also known as the 'Area'
    int ax = x - 512;
    int ay = y - 384;
    int zx = ax / 1024;
    int zy = ay / 768;
    if (ax < 0) --zx;
    if (ay < 0) --zy;

    // ZoneCoords
    int NWzx = zx; int NWzy = zy;   int NEzx = zx+1; int NEzy = zy;
    int SWzx = zx; int SWzy = zy+1; int SEzx = zx+1; int SEzy = zy+1;

    Coords2i NW(NWzx, NWzy);
    Coords2i NE(NEzx, NEzy);
    Coords2i SW(SWzx, SWzy);
    Coords2i SE(SEzx, SEzy);

    Coords2i CurrZC;

    Area::iterator iter;
    for (iter = area.begin(); iter != area.end(); ++iter)
    {
        CurrZC = iter->ZoneCoord;
        if (CurrZC == NW)
            ZT.NW = &(*iter);
        if (CurrZC == NE)
            ZT.NE = &(*iter);
        if (CurrZC == SW)
            ZT.SW = &(*iter);
        if (CurrZC == SE)
            ZT.SE = &(*iter);
    }
}
Anyhow. Lemme re-view this post...
...
Yeah, I've lost my mind. If anyone has some stories of how they handled dynamically generated content - particularly as it applies to a 2D scrolling environment - please share.

- M