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.

C/C++ > Variables behaving strangely

#173873 - zelbo - Wed May 05, 2010 9:36 pm

Working on a sudoku solver for the DS, but i'm running into some odd behavior, which i'm sure is due to my lack of understanding of C/C++.

Two main problems right now, one of them minor but seems to be connected to the other.

When i move my cursor around, it changes a value that it should not be changing (int cel.is).

At first, it was only when my cursor moved up and down. After i tried different ways of initializing the cursor position, the value changed only during left/right movement. This is very troubling to me. Syntax error maybe?

The other problem is that i have tried to initialize the starting position of the cursor both during the constructor and immediately after creating the cursor object. Neither seems to work, although my cursor movement code seems to work fine (other than the problem mentioned above).
I'm aware that i'm using naked arrays and have no asserts, working on adding those now.

relevant parts of sudoku.cpp:
Code:
Sudoku::Sudoku()
{
   initVideo();
   //initBackground();   //seem to have broken the backgrounds, low priority for now. solver engine more important.
   initGraphics();
   initText();
   state = STATE_EDIT;
   
   Cursor * cursor = new Cursor(CURSOR_OAM_ID);
   
   cursor->x = 5;
   cursor->y = 5;
   
   cursor->gfx = oamAllocateGfx(&oamMain, SpriteSize_8x8, SpriteColorFormat_16Color);
    dmaCopyHalfWords(SPRITE_DMA_CHANNEL, cursor_spriteTiles, cursor->gfx, cursor_spriteTilesLen);
   dmaCopyHalfWords(SPRITE_DMA_CHANNEL, cursor_spritePal, SPRITE_PALETTE, cursor_spritePalLen);

}
void Sudoku::edit()
{

// select cel (set current_cel, block, row, column)
   if(pressed & KEY_UP and cursor->y > TOP_BOUNDARY) cursor->move(UP);
   if(pressed & KEY_DOWN and cursor->y < BOTTOM_BOUNDARY) cursor->move(DOWN);
   if(pressed & KEY_LEFT and cursor->x > LEFT_BOUNDARY) cursor->move(LEFT);
   if(pressed & KEY_RIGHT and cursor->x < RIGHT_BOUNDARY) cursor->move(RIGHT);
   
// edit current_cel (touchpad)

}

void Sudoku::draw()
{
   swiWaitForVBlank();

   consoleSelect(&consoleTop);// use console for now, while getting guts working, get fancy later
   consoleClear();
   
   // begin "this is horrid, fix this"
   iprintf("%i%i%i %i%i%i %i%i%i\n", cel[0]->display(), cel[1]->display(), cel[2]->display(), cel[3]->display(), cel[4]->display(), cel[5]->display(), cel[6]->display(), cel[7]->display(), cel[8]->display());
   iprintf("%i%i%i %i%i%i %i%i%i\n", cel[9]->display(), cel[10]->display(), cel[11]->display(), cel[12]->display(), cel[13]->display(), cel[14]->display(), cel[15]->display(), cel[16]->display(), cel[17]->display());
   iprintf("%i%i%i %i%i%i %i%i%i\n\n", cel[18]->display(), cel[19]->display(), cel[20]->display(), cel[21]->display(), cel[22]->display(), cel[23]->display(), cel[24]->display(), cel[25]->display(), cel[26]->display());
   
   iprintf("%i%i%i %i%i%i %i%i%i\n", cel[27]->display(), cel[28]->display(), cel[29]->display(), cel[30]->display(), cel[31]->display(), cel[32]->display(), cel[33]->display(), cel[34]->display(), cel[35]->display());
   iprintf("%i%i%i %i%i%i %i%i%i\n", cel[36]->display(), cel[37]->display(), cel[38]->display(), cel[39]->display(), cel[40]->display(), cel[41]->display(), cel[42]->display(), cel[43]->display(), cel[44]->display());
   iprintf("%i%i%i %i%i%i %i%i%i\n\n", cel[45]->display(), cel[46]->display(), cel[47]->display(), cel[48]->display(), cel[49]->display(), cel[50]->display(), cel[51]->display(), cel[52]->display(), cel[53]->display());
   
   iprintf("%i%i%i %i%i%i %i%i%i\n", cel[54]->display(), cel[55]->display(), cel[56]->display(), cel[57]->display(), cel[58]->display(), cel[59]->display(), cel[60]->display(), cel[61]->display(), cel[62]->display());
   iprintf("%i%i%i %i%i%i %i%i%i\n", cel[63]->display(), cel[64]->display(), cel[65]->display(), cel[66]->display(), cel[67]->display(), cel[68]->display(), cel[69]->display(), cel[70]->display(), cel[71]->display());
   iprintf("%i%i%i %i%i%i %i%i%i\n\n", cel[72]->display(), cel[73]->display(), cel[74]->display(), cel[75]->display(), cel[76]->display(), cel[77]->display(), cel[78]->display(), cel[79]->display(), cel[80]->display());
   // end "this is is horrid, fix this"
   
   consoleSelect(&consoleBottom);
   consoleClear();
   iprintf("123456789\n");
   
   iprintf("Touch x = %04i, %04i, %02i\n", touch.rawx, touch.px, touch.px >> 3);
   iprintf("Touch y = %04i, %04i, %02i\n", touch.rawy, touch.py, touch.py >> 3);
   iprintf("cursor x, y = %02i, %02i\n", cursor->x, cursor->y);
   iprintf("cel 0 is %i\n", cel[0]->display());

   oamSet(&oamMain, CURSOR_OAM_ID, (cursor->x * TILE_SIZE), (cursor->y * TILE_SIZE), CURSOR_LAYER, 0, SpriteSize_8x8,
      SpriteColorFormat_16Color, cursor->gfx, -1, false, false,  false, false, false);
   
//   bgSetScroll(bgCursor, screen->x, screen->y);
   bgUpdate();
   oamUpdate(&oamMain);

}


cursor.hpp:
Code:
class Cursor
{
   public:
      u16* gfx;
      int x, y;
      int oamID;

      Cursor(int ID);
      ~Cursor();
      void move(int direction);
   protected:
};


cursor.cpp:
Code:
Cursor::Cursor(int ID)
{
   oamID = ID;
   // why are these not getting set?
   x = 5;
   y = 5;
}

Cursor::~Cursor()
{
   ;
}

void Cursor::move(int direction)
{
   if(direction == UP)
   {
      y--;
      if(y == TOP_BREAK) y--;
      if(y == BOTTOM_BREAK) y--;
   }
   else if(direction == DOWN)
   {
      y++;
      if(y == TOP_BREAK) y++;
      if(y == BOTTOM_BREAK) y++;
   }
   else if(direction == LEFT)
   {
      x--;
      if(x == LEFT_BREAK) x--;
      if(x == RIGHT_BREAK) x--;
   }
   else if(direction == RIGHT)
   {
      x++;
      if(x == LEFT_BREAK) x++;
      if(x == RIGHT_BREAK) x++;
   }
   else ;   //drink!
}


cel.hpp: (note protected nature of the "is" variable)
Code:
class Cel
{

public:
   Cel();
   virtual ~Cel();
   int set(int new_value);
   int display();
   bool can_be(int value);
   
private:

protected:
   int is;
   bool potential[9];

};


cel.cpp:

Code:
Cel::Cel()
{
   is = 0;
   int i;
   for(i = 0; i < 9; i++) potential[i] = true;
}

Cel::~Cel()
{
}

int Cel::set(int new_value)
{
   int i;
   if(new_value == 0)
   {
      for(i = 0; i < 9; i++) potential[i] = true;
      is = new_value;
   }
   else
   {
      for(i = 0; i < 9; i++) potential[i] = false;
      potential[new_value] = true;
      is = new_value;
   }
   return 0;
}

int Cel::display()
{
   // maybe make a string or char and output the display string (" ", "1", "2"...)
   int value = is;
   return value;
}

bool Cel::can_be(int value)
{
   return potential[value];
}


I find this very strange, especially since the "is" variable is protected and so far the only place i know of that i'm doing anything to it is during initialization of the cel.

Let me know if more information is needed. I know i'm not that good at this stuff yet, but just getting this simple thing working is seeming harder than it should be. What the heck am i doing wrong?

#173874 - DiscoStew - Wed May 05, 2010 11:06 pm

Code:
Cursor * cursor = new Cursor(CURSOR_OAM_ID);


This is within your Sudoku constructor, which becomes lost in memory after leaving the constructor because it has no relationship to anything except being generated locally. If the Sudoku class has "cursor" as a member, then change the line to....

Code:
cursor = new Cursor(CURSOR_OAM_ID);


...and make sure to delete it when your Sudoku object terminates.

Remember, if you have two or more variables or the same exact name, each set in a particular layer of code, the inner one will always be used for manipulation, like so...

Code:

{
   int x = 1;
   {
      int x = 2; // outer x is ignored, but still exists
      {
         int x = 3; // outer x is ignored, but still exists
         // x = 3
      }
      // x now equals 2 because the inner 'x' was terminated
   }
   // x now equals 1 because the inner 'x' was terminated
}

_________________
DS - It's all about DiscoStew

#173875 - zelbo - Wed May 05, 2010 11:29 pm

That fixed both problems! Thank you.