gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

Coding > Problem with my dynamic tile manager...

#12366 - rooter - Sun Nov 09, 2003 5:29 am

Ok, I'm having some problems my dynamic tile management. Most of this code is taken off of booflys code... basically when i scroll around im getting some corruption... its all FINE at first, perfect, spectacular, but when i start scrolling around i get garbaged tiles and just some wholly black tiles... im using a 48x32 map with 1100 tiles

summary:
works inititally just fine, tiles are read in even works perfectly on some small maps... when i scroll around a lot i get corruption and garbaged tiles... any ideas?

here's the code...

tileset.cpp
Code:

#include "tileset.h"

CTileset::CTileset()
{
    stackPtr = -1;
    for (u16 count=MAXVRAM-1;count>0;count--)
    {
        used[count] = 0;
        Push(count);
    }
    for (u16 a=0;a<MAXTILES;a++)
        mapUse[a] = -1;

    used[0] = 1;

    tiles = NULL;
}

CTileset::~CTileset()
{
}

void CTileset::SetTileset(u8 *tileset)
{
    tiles = tileset;
}

u16 CTileset::AddCharacter(u16 charNum)
{
    s16 memPlace = mapUse[charNum];

    if (memPlace < 0)
    {
        memPlace = Pop();
        if (memPlace >= 0)
        {
            REG_DMA3SAD = ((u32)tiles + (charNum << 6));
            REG_DMA3DAD = (0x06004000 + (memPlace<< 6));
            REG_DMA3CNT = 16 | DMA_32NOW;
            mapUse[charNum] = memPlace;
            rLUT[memPlace] = charNum;
        }
    }
    if (memPlace > 0)
        used[memPlace]++;
    return memPlace;
}

void CTileset::RemoveCharacter(u16 charNum)
{
    if (charNum != 0)
    {
        used[charNum]--;
        if (used[charNum] == 0)
        {
            mapUse[rLUT[charNum]] = -1;
            Push(charNum);
        }
    }
}

void CTileset::Push(u16 charNum)
{
    stackPtr++;
    stack[stackPtr] = charNum;
}

u16 CTileset::Pop()
{
    s16 pop = -1;

    if (stackPtr >= 0)
    {
        pop = stack[stackPtr];
        used[stackPtr] = 0;
        stackPtr--;
    }
    return pop;
}


tileset.h
Code:
#include "gba.h"

#define MAXTILES 8192
#define MAXVRAM 750

class CTileset
{
    public:
    CTileset();
    ~CTileset();
   
    u16 AddCharacter(u16 charNum);
    void SetTileset(u8 *tileset);
    void RemoveCharacter(u16 charNum);
   
    private:
    void Push(u16 charNum);
    u16 Pop();
   
    s16 stack[MAXVRAM];
    s16 stackPtr;
    s16 used[MAXVRAM];
    s16 rLUT[MAXVRAM];
    int mapUse[MAXTILES];
    u8 *tiles;
};


layer.cpp
Code:
void CLayer::Update(int x, int y, int width, int height)
{
    int tile = 0, newchar = 0;
    for (int cX = 0; cX < width; cX++)
    {
        for (int cY = 0; cY < height; cY++)
        {
            if ((y==1) && (x > 1))
            {
                if ((cY+y+21) < sY)
                {
                    tile = bg[(((cY+y)&31) * 32) + ((cX + x)&31)];
                    tileset->RemoveCharacter(tile);
                    newchar = data[((cY+y) * sX) + cX + x];
                    tile = tileset->AddCharacter(newchar);
                    bg[(((cY+y)&31) * 32) + ((cX + x)&31)] = tile;
                }
            }
            else
            {
                tile = bg[(((cY+y)&31) * 32) + ((cX + x)&31)];
                tileset->RemoveCharacter(tile);
                tile = tileset->AddCharacter(data[((cY+y) * sX) + cX + x]);
                bg[(((cY+y)&31) * 32) + ((cX + x)&31)] = tile;
            }
        }
    }
}

#12368 - rooter - Sun Nov 09, 2003 7:24 am

sort of fixed it, i added the reclaim function that was in boo's code but im still getting a few random garbage or misplaced tiles onscreen at a time, but not the HUGE black areas i was getting before

#12434 - rooter - Thu Nov 13, 2003 2:02 am

all fixed! thanks guys =P