Several bugs I can't understand

SuperKd1302

New Member
OP
Newbie
Joined
May 14, 2023
Messages
1
Trophies
0
Age
20
XP
162
Country
France
EDIT : I found the solution. The call "currentImage->getWidth()" returns the image width (here : 512), but when I enter the main loop of the program it will always return 0 (so I guess the variable "width" changes to 0). To solve the issue, I changed the variable to "public" instead of "private" in the class Image. : now the function always returns 512. Why is that? To me it looks totally unrelated...

Hello guys,

With a friend, I'm currently creating an image editor for the DS.
We use the A and B banks of VRAM to store a 512x512 background (containing u8 values that are the indices of the screen palette, BG_PALETTE) that will be displayed on the bottom screen (as the "main" screen). The top screen displays a console by using consoleDemoInit().

Code:
    videoSetMode( MODE_5_2D );
    videoSetModeSub( MODE_5_2D );
    vramSetBankA(VRAM_A_MAIN_BG);
    vramSetBankB(VRAM_B_MAIN_BG);
    //vramSetBankC(VRAM_C_SUB_BG);
    consoleDemoInit();
    lcdMainOnBottom();
   
    int bg = bgInit(3, BgType_Bmp8, BgSize_B8_512x512, 0, 0);
    //int bgSub = bgInitSub(3, BgType_Bmp16, BgSize_B16_256x256, 0, 0);
   
    u16* vms = bgGetGfxPtr(bg);
    //u16* vms2 = bgGetGfxPtr(bgSub);
   
    videoBgEnable(3);  
    //videoBgEnableSub(3);

The image is stored in ram, the data structure looks like this :

Code:
class Image
{
private:
    const char * name;
    u16 width;
    u16 height;
    u16 palette[256];
    u8* pixels;
public:
    Image(const char * = "name.dsif", u16 = 512, u16 = 512);
    ~Image();
    static Image* readImage(const char * filename);
    void writeImage();
    u8* getPixels();
    u16 getColor(u32, u32);
    inline u16 getWidth(){return this->width;}
    u16* getPalette();
};
In the constructor, we allocate an array in RAM to store the pixels
this->pixels = new u8[this->width * this->height];

We continue with the initialization in main.cpp

Code:
    u8* ptr = new u8[262144];

    Image* current_image = new Image("name.dsif", 512, 512);
   
    dmaCopyWords(0, current_image->getPalette(), BG_PALETTE, 512);
    imageOnBg(0, 0, 512, 512, ptr, current_image);
   
    dmaCopyWords(0, ptr, vms, 262144);

    Tool* currentTool = new Tool(-1, -1);

The line "imageOnBg" copies a 512x512 chunk of the image in a buffer called "ptr", stored in RAM. The user modifications will first take place on the buffer, and every frame where there's a modification, we update the 512x512 background, thanks to the pointer "vms" that we obtained earlier with bgGetGfxPtr(bg).

Then starts the main loop with "while(1)". We first verify if any key has been pressed. If the R key is pressed, we change the current "mode". For now, we have 3 modes : pencil, line, and curve.

Every time we switch modes we set updateImage to true. That will execute this code at the end of the frame :

Code:
    BgOnImage(0, 0, 512, 512, ptr, current_image);
    updateImage = false;

The BgOnImage function used to look like this :

Code:
void BgOnImage(int x1, int y1, int x2, int y2, u8* buffer, Image* image)
{
    u8* pixels = image->getPixels();
    for (int j = y1; j < y2; j++)
    {
        for (int i = x1; i < x2; i++)
        {
            *(pixels + i + j * image->getWidth()) = *(buffer + i + j * LENGTH_MAIN);
            if(i == 5 && j == 5)
            {
                iprintf("%d -- %d || ", *(pixels + 5 + 5 * image->getWidth()), *(buffer + 5 + 5 * LENGTH_MAIN));
            }
        }
    }
    iprintf("%d -- %d", *(pixels + 5 + 5 * image->getWidth()), *(buffer + 5 + 5 * LENGTH_MAIN));
}

So I first check in the loop if the pixel(5, 5) of the image is of the same value as the one from the ptr buffer. And that's the case.
But when I go out of the loop, and do the same thing, the pixel(5, 5) of the image has its value changed back to its previous one, before the affectation!
Maybe you wonder why I use a buffer in RAM, instead of just copying the VRAM background to the image and vice-versa. Well, I had a similar problem. I couldn't change the values of the VRAM background, the same way I can't change the image here (Actually, I can change the values if I use a u16 pointer for the VRAM (before we used a background that used no palette for the top screen), but not a u8 pointer). To solve the issue, I created the ptr buffer, and whenever I want to update the screen, I use the libnds function dmaCopyWords() to copy the whole buffer to the VRAM.

So I tried something similar :
Code:
    u8* pixels = image->getPixels();
    for (int j = y1; j < y2; j++)
    {
        dmaCopyWords(0, buffer + x1 + j * LENGTH_MAIN, pixels + x1 + j * image->getWidth(), x2 + 1 - x1);
    }
    iprintf("%d -- %d", *(pixels + 5 + 5 * image->getWidth()), *(buffer + 5 + 5 * LENGTH_MAIN));
But the 5,5 pixel of the image is still not of the same value as the buffer's one.

Thanks for your help !
 
Last edited by SuperKd1302,

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Psionic Roshambo @ Psionic Roshambo: This parrot is no more it has ceased to be!