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.

DS development > When things should work and they don't...

#148865 - onimatrix - Fri Jan 11, 2008 3:49 pm

Hello homebrew community, I'm new to this art and I grew frustrated in the past week trying to solve what is a mystery to me.

Look at this code, please:

Code:
#include <nds.h>
#include "graphics.h"
#include "defines.h"


int main(void)
{   
    powerON(POWER_ALL_2D);
   
   irqInit();
   irqEnable(IRQ_VBLANK);
   
    videoSetMode(MODE_5_2D | DISPLAY_BG2_ACTIVE);
    vramSetBankA(VRAM_A_MAIN_BG);
    BG2_CR = BG_BMP16_256x256;
   
    BG2_XDX = 1 << 8;
    BG2_XDY = 0;
    BG2_YDX = 0;
    BG2_YDY = 1 << 8;
    BG2_CY = 0;
    BG2_CX = 0;
   
    videoSetModeSub(MODE_5_2D | DISPLAY_BG2_ACTIVE);
    vramSetBankC(VRAM_C_SUB_BG);
    SUB_BG2_CR = BG_BMP16_256x256;
   
    SUB_BG2_XDX = 1 << 8;
    SUB_BG2_XDY = 0;
    SUB_BG2_YDX = 0;
    SUB_BG2_YDY = 1 << 8;
    SUB_BG2_CY = 0;
    SUB_BG2_CX = 0;

    while(1)
    {
        swiWaitForVBlank();
        DrawPixel(12, 12, cWALL);   
        DrawPixel(13, 12, cWALL);   
        DrawPixel(14, 12, cWALL);   
        DrawPixel(15, 12, cWALL);   
        DrawPixel(16, 12, cWALL);   
        DrawPixel(17, 12, cWALL);           
    }
    return false;
}


It should be noted that cWALL is defined in defines.h as "RGB15(31, 0, 0) | BIT(15)", that false is defined as 0 in the same file and that DrawPixel is defined in graphics.c as

Code:
void DrawPixel(u8 x, u8 y, u16 color)
{
    VRAM_A[y * SCREEN_WIDTH + x] = color;
}


The thing is that this code works in iDeaS, but not in no$gba nor in the real hardware.

As you can see, I'm just messing around giving my first steps in this area.
My job keeps me chained to J2ME and I need some fresh air.


Last edited by onimatrix on Fri Jan 11, 2008 5:01 pm; edited 1 time in total

#148867 - eKid - Fri Jan 11, 2008 4:11 pm

Your problem is:
Code:
VRAM_A[y * SCREEN_WIDTH + x] = color;

It should be changed to:
Code:
BG_GFX[y * SCREEN_WIDTH + x] = color;

VRAM_A is a pointer for when the bank is set to 'LCDC' mode. BG_GFX is a pointer for when the bank is set for background graphics. :)

#148869 - onimatrix - Fri Jan 11, 2008 4:13 pm

Ohhhh, that makes sense.

Thank you eKid, I was going to stick my stylus into my ear.

#148873 - onimatrix - Fri Jan 11, 2008 5:00 pm

Sorry to be such a newbie, but I'm having a wierd problem with my code. When SIZE_X and SIZE_Y are 124, the DS shows what it should, but when they are 125 it crashes and burns. The rest of the code remains the same, and subDrawPixel draws to BG_GFX_SUB instead of BG_GFX.

Code:
    s8 terrain[SIZE_X][SIZE_Y];
   
    s16 cX;
    s16 cY;
   
    for (cY = 0; cY < SIZE_Y; cY++)
    {
        for (cX = 0; cX < SIZE_X; cX++)
        {
            terrain[cX][cY] = EMPTY;
        }
    }

    terrain[12][12] = WALL;
    terrain[12][13] = WALL;
    terrain[12][14] = WALL;
    terrain[12][15] = WALL;
    terrain[12][15] = WALL;

    while(true)
    {
        swiWaitForVBlank();
       
        for (cY = 0; cY < SIZE_Y; cY++)
        {
            for (cX = 0; cX < SIZE_X; cX++)
            {
                if (terrain[cX][cY] == EMPTY)
                {
                    DrawPixel(cX, cY, cEMPTY);
                    subDrawPixel(cX, cY, cEMPTY);
                }
                if (terrain[cX][cY] == WALL)
                {
                    DrawPixel(cX, cY, cWALL);
                    subDrawPixel(cX, cY, cWALL);
                }               
            }
        }
    }
   

#148876 - eKid - Fri Jan 11, 2008 5:07 pm

You are probably using too much stack memory, theres only 16kb of stack space afaik. 125*125 = almost 16kb. Try moving terrain to a global spot outside the function.

#148878 - onimatrix - Fri Jan 11, 2008 5:10 pm

It worked! :D

You rock eKid, thanks for your time and experience :)

#149120 - silent_code - Tue Jan 15, 2008 5:07 pm

or (in general) you could allocate heap memory by using a pointer and new/delete. ;^)
well, if the data is used rather frequently you could still stick to the global array.
i'm a bit mixed right now... wouldn't a static declaration of the local variable help that too? that way that data wouldn't be global or file global (a static global) and still wouln't use up stack memory. ... or am i wrong? (can't remember static function variable allocation anymore! got to read that up!)

#149121 - onimatrix - Tue Jan 15, 2008 5:10 pm

I finally used the extern global variable approach, as this is the most used variable in my tilemap editor. BTW, is coming along nicely. I have only to find out how can I save data directly to a file in my R4.

#149147 - tepples - Wed Jan 16, 2008 1:11 am

onimatrix wrote:
I have only to find out how can I save data directly to a file in my R4.

Do you want to see a quick "hello world" example, which uses libfat to write a text file called "/data/hello/hello.txt"?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#149186 - onimatrix - Wed Jan 16, 2008 2:08 pm

tepples wrote:
onimatrix wrote:
I have only to find out how can I save data directly to a file in my R4.

Do you want to see a quick "hello world" example, which uses libfat to write a text file called "/data/hello/hello.txt"?


I remembered all my saturday nights writing software in C, so fprintf worked perfectly for text mode.

The thing is that my file will be conformed by the following data:

Header
ID: 2 bytes
Width: 2 bytes
Height: 2 bytes
X Position in the general map: 2 bytes
Y Position in the general map: 2 bytes
Initial X Position of the viewport: 2 bytes
Initial Y Position of the viewport: 2 bytes

Tile map
Lossless compresion of a 2D array.
Tile header: 2 bytes
Tile data: 2 bytes

Item list
Item header: 4 bytes
Item data: 4 bytes

Text mode is kind of out of the question :P

#149187 - kusma - Wed Jan 16, 2008 2:16 pm

onimatrix wrote:
Text mode is kind of out of the question :P


look up fwrite() and fread(). They're what you'll need to write binary files. Also make sure you open your file in binary mode (as in fopen(filename, "wb")), as on some platforms bit 8 of every byte gets removed in ascii mode.

#149188 - onimatrix - Wed Jan 16, 2008 2:20 pm

kusma wrote:
onimatrix wrote:
Text mode is kind of out of the question :P


look up fwrite() and fread(). They're what you'll need to write binary files. Also make sure you open your file in binary mode (as in fopen(filename, "wb")), as on some platforms bit 8 of every byte gets removed in ascii mode.


Yep, I was thinking about them. I'm searching the web for examples on a nice way to pack all this data without going rabid monkey :)

Thanks kusma.

#149199 - PypeBros - Wed Jan 16, 2008 5:38 pm

it might not be a very good tutorial, but i can offer this code as an example of reading "packed" structures out of a file.

As for "packing the data" in the file, i typically use perl functions, but simply producing array of bytes on a PC (from another C program) and fwrite()ing them to the file would be fine too.
_________________
SEDS: Sprite Edition on DS :: modplayer

#149202 - onimatrix - Wed Jan 16, 2008 5:45 pm

PypeBros wrote:
it might not be a very good tutorial, but i can offer this code as an example of reading "packed" structures out of a file.

As for "packing the data" in the file, i typically use perl functions, but simply producing array of bytes on a PC (from another C program) and fwrite()ing them to the file would be fine too.


Funny, I didn't know that there was an interpreter of Perl to use in the DS :S
I don't need that kind of sofistication anyways, I'm thinking of fwriting all the bytes continously and parsing the stuff as it gets fread. After all, I would only need to add the size of the tile map data in the header, as it is the only place where the size will change (Lossless compression and it's variable bit rate... ??u)

Thanks for the tip PypeBros :)

#149253 - PypeBros - Thu Jan 17, 2008 9:55 am

onimatrix wrote:

Funny, I didn't know that there was an interpreter of Perl to use in the DS :S

Not yet, to my best knowledge, except maybe for DSLinux ;)
Not that it would be hard to do, but i doubt i'd be of any use

No, i was suggesting preparing the binary data with a scripted language (e.g. Perl) on your PC (rather than building a C file where you typed the data in a large array and that write them on disk).
_________________
SEDS: Sprite Edition on DS :: modplayer

#149264 - onimatrix - Thu Jan 17, 2008 2:09 pm

Trouble is that this is going to be sort of a suite of apps for the DS to develop new content for my game. Tile map editor, tile editor, scripting engine (REALLY BASIC just now) and both an enemy and an item's editor too.


BTW, last night I got the thing working. Making the map resizeable was the biggest challenge, having to change from a 2D array to a dynamic list (As I couldn't declare the array using non constant values :) )

#149265 - PypeBros - Thu Jan 17, 2008 2:39 pm

Lol. Exactly the kind of things i'm trying to achieve myself.

I already have a "tile editor" started, and very basic scripting engine. So far, i just import maps from flat pictures with the perl tool mentionned above.

Let me know if you're open to a collaboration ...
_________________
SEDS: Sprite Edition on DS :: modplayer

#149266 - onimatrix - Thu Jan 17, 2008 2:57 pm

I'm always open to collaboration.
If you need to know how I achieved something just ask.
For the moment we are, like, 12 people in the project, though I'm currently the only one that can tell VRAM from his ass.

BTW, nice tile designer :D