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 > typedef struct crashes my rom!

#127595 - Lotti - Thu May 03, 2007 1:59 pm

here is the code!

0 compile errors or warnings

when i run this rom with no$gba i've got: "the rom-image has crashed"

when i run this on nds i got black screens.

this is the code:

Code:

// Includes
#include <PA9.h>       // Include for PA_Lib
#include <fat.h>

typedef struct
{
   char question[512];
   char A[512];
   char B[512];
   char C[512];
   char D[512];
   u8   answer;   
   u8   done;
} entry;

// Function: main()
int main(int argc, char ** argv)
{
   u8 fatok=0;
   u16 totdomande=0;             
   entry domande[100];

   PA_Init();    // Initializes PA_Lib
   PA_InitVBL(); // Initializes a standard VBL

   PA_InitText(1, 0);  // Initialise the text system on the top screen
   PA_InitText(0, 0);  // Initialise the text system on the bottom screen
   
   PA_WaitForVBL();
   
   PA_OutputText(0,7,11,"Welcome to WWTBAFM!");      
   PA_OutputText(1, 0, 0, "Initializing Fat...");

   if (!fatInitDefault()) //Initialise fat library
      {
         PA_OutputText(1, 0, 1, "Fat Error");
         PA_OutputText(1, 0, 2, "Do you have patched this rom");
         PA_OutputText(1, 0, 3, "with the correct DLDI driver?");
      }
   else
        {PA_OutputText(1, 0, 1, "Fat OK!"); fatok=1;}


if (fatok)
{   
   char filename[] = "/WWTBAFM/questions.txt";   
   FILE* file = fopen (filename, "r");   
   
   if(file==NULL) PA_OutputText(1,0,2,"Unable to open %s", filename);
   else
   {
     PA_OutputText(1,0,2,"Opening %s", filename);
     PA_OutputText(1,0,3,"Loading from file");
     char c[512];
     while(!feof(file))
     {
//crashing part
        fgets(domande[totdomande].question, 512, file);
        fgets(domande[totdomande].A, 512, file);
        fgets(domande[totdomande].B, 512, file);
        fgets(domande[totdomande].C, 512, file);
        fgets(domande[totdomande].D, 512, file);
         fgets(c, 512, file);
        domande[totdomande].answer=c[0]-48;
        domande[totdomande].done=0;
        totdomande++;
//end crashing part
     }
     fclose(file);
   
     PA_OutputText(1,0,4,"Load Complete!");
     PA_OutputText(1,0,5,"Press Start to begin");   
     PA_WaitFor(Pad.Newpress.Start);     
   
   u8 i,j,givenanswer;
   u16 correctanswers=0;
   for (i=0;i<totdomande;i++)
   {
      PA_InitText(1, 0);  // Initialise the text system on the top screen
      PA_InitText(0, 0);  // Initialise the text system on the bottom screen

      PA_OutputText(0,1,22,"Correct Answers: %03d", correctanswers);
      
      do {j=PA_RandMax(totdomande);}
      while (domande[j].done==1);
      PA_OutputText(1,0,1,"Question N.%03d", i);
      PA_BoxText(1, 2, 3, 29, 21, domande[j].question, (29 - 2)*(21 - 3));   
      PA_OutputText(0,1,2, "A) %s", domande[j].A);
      PA_OutputText(0,1,4, "B) %s", domande[j].B);
      PA_OutputText(0,1,6, "X) %s", domande[j].C);
      PA_OutputText(0,1,8, "Y) %s", domande[j].D);                  
      
      givenanswer=0;      
      while (givenanswer==0)
      {
         if (Pad.Newpress.A)  givenanswer=1;
          else if (Pad.Newpress.B)  givenanswer=2;
          else if (Pad.Newpress.X)  givenanswer=3;
         else if (Pad.Newpress.Y)  givenanswer=4;
         else givenanswer=0;
      }      
      domande[j].done=1;
     
      if (givenanswer==domande[j].answer) correctanswers++;
   }         
  }
}      
      
   // Infinite loop to keep the program running
   while (1)
   {
      PA_WaitForVBL();
   }
   
   return 0;
} // End of main()

_________________
http://lottisden.blogspot.com/

#127601 - Lick - Thu May 03, 2007 2:30 pm

Try declaring entry domande[100]; like this:

Code:
static entry domande[100];
or
Code:
entry *domande = new entry[100];
or
Code:
entry *domande = (entry*)malloc(sizeof(entry) * 100);

_________________
http://licklick.wordpress.com

#127607 - Lotti - Thu May 03, 2007 3:06 pm

Lick wrote:
Try declaring entry domande[100]; like this:

Code:
static entry domande[100];
or
Code:
entry *domande = new entry[100];
or
Code:
entry *domande = (entry*)malloc(sizeof(entry) * 100);

they seems to work. expect for the "new" (that i abitually use) because it isn't declared.. what libreries i have to add to use "new" function?
_________________
http://lottisden.blogspot.com/

#127610 - tepples - Thu May 03, 2007 3:32 pm

You have to name your files to end in ".cpp" and compile and link with g++ in order for new to work. No, I don't know what triggers linking with g++ in wintermute's build system.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#127617 - Lick - Thu May 03, 2007 4:24 pm

tepples wrote:
You have to name your files to end in ".cpp" and compile and link with g++ in order for new to work. No, I don't know what triggers linking with g++ in wintermute's build system.

That should do the trick, but Lotti is using PALib so his Makefiles may not be the same.

#127627 - Rajveer - Thu May 03, 2007 5:49 pm

I haven't had the greatest of luck with the PALib and it's makefile. It seems to do weird things like placing data in DTCM, a problem I had not long ago. I would suggest using libnds without PALib if you can and compiling with one of the template libnds makefiles, it doesn't look like you use alot of different PALib commands, mainly for outputting text and so on. But if you insist on using PALib then sorry I'm of no use!

#127660 - Lotti - Thu May 03, 2007 10:48 pm

well actually i need palib just to output text. then this game will use backgrounds and 2d sprites. i don't know how to code this with libnds. the biggest problem is that there isn't any supereasy tutorial :) but this is another topic of discussion :P i'll try the "new" function with .cpp.

i tried the other 2 but the program never fills in the structs. they're always blank :\
_________________
http://lottisden.blogspot.com/

#127695 - tepples - Fri May 04, 2007 3:12 am

There are ways to output text other than palib. Do you know how to draw the alphabet in tiles?
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#127699 - HyperHacker - Fri May 04, 2007 4:42 am

FYI, the problem is you run out of stack space. Your struct is (512*5)+2 = 2562 bytes, and you declare 100 of them (256,200 bytes, ~250.1 KB) as a local variable. Locals get put on the stack and I can assure you the stack is not 250 KB. (Anyone know how big it is?)
_________________
I'm a PSP hacker now, but I still <3 DS.

#127717 - simonjhall - Fri May 04, 2007 7:56 am

normally, 16k :-D
_________________
Big thanks to everyone who donated for Quake2

#127729 - Lotti - Fri May 04, 2007 10:24 am

however it works! i used the new function. structs aren't blank. and i declared 100 of them :P

thank you for the support. you will see this nice homebrew in the future 2-3 months :)
_________________
http://lottisden.blogspot.com/

#127742 - Lick - Fri May 04, 2007 12:32 pm

When you use 'static' or simply allocate memory with 'new' or 'malloc', the data is NOT put on the stack. I am not really sure where the 'static' data goes, but allocated data goes into the Main RAM.

So congratulations, you're using the Main RAM. :D
_________________
http://licklick.wordpress.com

#127748 - tepples - Fri May 04, 2007 1:34 pm

'static' data goes alongside global variables, that is, in main memory.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#127784 - HyperHacker - Sat May 05, 2007 12:02 am

Doing this:
Code:
void DoSomethingCool() {
static int foo;
}


is the same as doing this:
Code:
int foo;
void DoSomethingCool() {
[...]
}


except that in the first case, foo can only be accessed within DoSomethingCool(), and you can have other variables named foo elsewhere. Otherwise it behaves the same: the variable is stored in main memory and retains its value between calls.
_________________
I'm a PSP hacker now, but I still <3 DS.

#127787 - Lotti - Sat May 05, 2007 12:37 am

http://lotti.altervista.org/ -> the homebrew that i'm developing.

pls contribute :)
_________________
http://lottisden.blogspot.com/

#127790 - Rajveer - Sat May 05, 2007 1:33 am

HyperHacker wrote:
Doing this:
Code:
void DoSomethingCool() {
static int foo;
}


is the same as doing this:
Code:
int foo;
void DoSomethingCool() {
[...]
}


except that in the first case, foo can only be accessed within DoSomethingCool(), and you can have other variables named foo elsewhere. Otherwise it behaves the same: the variable is stored in main memory and retains its value between calls.


So you can have multiple static variables called "foo" each declared in a separate function but existing globally, and specific foos are called in those functions retaining it's last value (as its "global")?

#127813 - HyperHacker - Sat May 05, 2007 8:40 am

Yes, if you mean what I think you mean. It's as if the compiler simply prepends the function name, so in this case:

Code:
int foo = 42;
void DoSomethingCool() {
static int foo = 1337;
[...]
foo = 27;
}

void DoSomethingElse() {
static int foo;
[...]
foo = 69;
}


It's as if you wrote this:
Code:
int foo = 42;
int DoSomethingCool_foo = 1337;
int DoSomethingElse_foo;

void DoSomethingCool() {
[...]
DoSomethingCool_foo = 27;
}

void DoSomethingElse() {
[...]
DoSomethingElse_foo = 69;
}


I imagine that's how the preprocessor handles it, but I've never checked.
_________________
I'm a PSP hacker now, but I still <3 DS.

#127823 - Lick - Sat May 05, 2007 11:14 am

To use the global variable you use this "::foo". (Not entirely sure if it works in C, but sure it works in C++).
_________________
http://licklick.wordpress.com