GamebuinoClassic archive

Archive of the Gamebuino Classic forum (2014-2018), rebuilt from the pages kept by the Wayback Machine: only part of the topics and pages were captured. Read-only. Removal on request: hi@gamebuino.com.

Forum › Programming Questions

gb.display.println() likes to fill screen with random chars

agentavacado Sat Aug 22, 2015 5:04 pm
I was trying to make a custom menu function, and then... Something odd happened... The function would act a lot like the average gb.menu() but I wanted to make custom graphics. So I started work on it, this is what I came up with:

Code: Select all
static unsigned const char PROGMEM ArrowRight[]=
{
  8,5,
  B11100,
  B11110,
  B11111,
  B11110,
  B11100,
};

const byte GBMenuSelect[] PROGMEM = {64,16,
0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x2,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x80,0x0,0x0,0x0,0x0,0x0,0x0,0x1,
0x40,0x0,0x0,0x0,0x0,0x0,0x0,0x2,
0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFC,
};

byte Menu(byte Length, String allElements[]) {
  //Length is 0 based
  boolean Exit = false;
  byte menuCursor = 0;
  byte menuSelected;
  //Delay, since a bug would prevent a second menu to be called(well, it would be skipped)
  int FrameDelay = 0;
  while (!Exit) {
    if (gb.update()) {
      FrameDelay++;
      if (FrameDelay >= 20) Exit = true;
      gb.display.drawPixel(0, FrameDelay);
    }
  }
  Exit = false;
  while (!Exit) {
    if (gb.update()) {
      gb.display.drawBitmap(0, 22, ArrowRight);
      gb.display.drawBitmap(10, 17, GBMenuSelect);
      //Temp, it should be A and B, not B and C
      gb.display.println("Press \"B\" to select");
      gb.display.print("\"C\" to Return");
      PrintHere(12, 24);
      gb.display.print(allElements[menuCursor]);
      PrintHere(0, 0);
    }
    if (gb.buttons.pressed(BTN_UP)) {
      byte menuCursorDes = menuCursor + 1;
      if (menuCursorDes <= Length) menuCursor++;
    }
    if (gb.buttons.pressed(BTN_DOWN)) {
      byte menuCursorDes = menuCursor - 1;
      if (menuCursorDes >= 0) menuCursor--;
    }
    if (gb.buttons.pressed(BTN_B)) {
      Exit = true;
      menuSelected = menuCursor;
    }
    if (gb.buttons.pressed(BTN_C)) Exit = true;
  }
  return menuSelected;
}


I tried calling it with this array:

Code: Select all
byte PAtt1 = 1;
byte PAtt2 = 0;
byte PAtt3 = 0;
byte PAtt4 = 0;

String NameAtt(byte Attack) {
  String AttackName = "Unknown";
  if (Attack == 0) AttackName = "Nothing";
  if (Attack == 1) AttackName = "Test 1";
  if (Attack == 2) AttackName = "Test 2";
  return AttackName;
}

String AllAttacks[] = {NameAtt(PAtt1), NameAtt(PAtt2), NameAtt(PAtt3), NameAtt(PAtt4)};


And the screen filled up with random numbers, symbols, and even words from the previous time it was called.
Creepypasta material.
When the menu is called it appears to work, saying "Test 1" in the box, but when you move your cursor...

I can't show you the image directly but here is a dropbox link:

After moving the cursor(it changes every second or so):
https://www.dropbox.com/s/n7s88qfkyscyvyc/Gamebuino%20bug%20after%20pressing%20a%20button.jpg?dl=0
agentavacado Wed Aug 26, 2015 2:08 am Re: gb.display.println() likes to fill screen with random ch
Since nobody has responded yet... It's rather nobody can figure out what's wrong with this code or you guys are in awe because the code error is so obvious and I can't see it. So I decided to fix a few things:

Code: Select all
byte Menu(byte Length, String allElements[]) {
  //Length is 0 based
  boolean Exit = false;
  byte menuCursor = 0;
  byte menuSelected;
  //Custom delay
  int FrameDelay = 0;
  while (!Exit) {
    if (gb.update()) {
      FrameDelay++;
      if (FrameDelay >= 10) Exit = true;
      //Shows that it's working
      gb.display.drawPixel(0, FrameDelay);
    }
  }
  Exit = false;
  while (!Exit) {
    if (gb.update()) {
      gb.display.drawBitmap(0, 22, ArrowRight);
      gb.display.drawBitmap(10, 17, GBMenuSelect);
      gb.display.println("Press \"A\" to select");
      gb.display.print("\"B\" to Return");
      PrintHere(12, 24);
      if (allElements[menuCursor] != NULL) {
        gb.display.print(allElements[menuCursor]);
      } else {
        gb.display.print("Null!");
      }
      PrintHere(0, 0);
    }
    if (gb.buttons.pressed(BTN_UP)) {
      int menuCursorDes = menuCursor - 1;
      if (menuCursorDes <= 0) menuCursor--;
    }
    if (gb.buttons.pressed(BTN_DOWN)) {
      int menuCursorDes = menuCursor + 1;
      if (menuCursorDes >= Length) menuCursor++;
    }
    if (gb.buttons.pressed(BTN_A)) {
      Exit = true;
      menuSelected = menuCursor;
    }
    if (gb.buttons.pressed(BTN_B)) Exit = true;
  }
  return menuSelected;
}


I changed the button inputs, and most importantly, an if statement that catches NULL and prints "Null!" instead of NULL.
It didn't fix anything.
Since I'm using a byte for menu cursor... If it goes under 0 it will jump to 255(which should be NULL, which I thought I protected, which I just realized... I'll fix it). But here's a small update. If it helps. Could it just be my gamebuino?
Sutchig Wed Aug 26, 2015 9:52 am Re: gb.display.println() likes to fill screen with random ch
i have only uneducated guesses ;)
in
Code: Select all
if (gb.buttons.pressed(BTN_UP)) {
      int menuCursorDes = menuCursor - 1;
      if (menuCursorDes <= 0) menuCursor--;
    }

you test if menuCursorDes is _below_ or equal 0 an then make menuCursor one smaller. So if menuCursor is 0, then menuCursorDes becomes -1 -> and menuCursor will be 255
Code: Select all
if (gb.buttons.pressed(BTN_UP)) {
      if (menuCursor > 0) menuCursor--;
    }

should do it (???)
For BTN_DOWN ist the same.

and I dont know, if allElements[menuCursor] != NULL really works...
agentavacado Wed Aug 26, 2015 8:49 pm Re: gb.display.println() likes to fill screen with random ch
You are correct with the byte jump, I changed menuCursor and menuCursorDes to int so the problem shouldn't be there anymore. I don't know what an empty array slot is... I thought it was NULL, but then again it should then be array out of bounds... Knowing this I'll fix my code and report back!
agentavacado Wed Sep 02, 2015 1:31 am Re: gb.display.println() likes to fill screen with random ch
I'm back with a working Menu(byte, String[]) function. I did do a few things to avoid bugs. The customDelay(int) function is just the 10 frame delay code from the last version.
Code: Select all
byte Menu(byte Length, String allElements[]) {
  //Length is 0 based
  boolean Exit = false;
  byte menuCursor = 0;
  byte menuSelected;
  customDelay(10);
  while (!Exit) {
    if (gb.update()) {
      gb.display.drawBitmap(0, 22, ArrowRight);
      gb.display.drawBitmap(10, 17, GBMenuSelect);
      gb.display.println("Press \"A\" to select");
      gb.display.print("\"B\" to Return");
      PrintHere(12, 24);
      if (allElements[menuCursor] != allElements[Length + 1]) {
        gb.display.print(allElements[menuCursor]);
      } else {
        gb.display.print("Empty!");
      }
      PrintHere(0, 0);
    }
    if (gb.buttons.pressed(BTN_UP)) {
      if (menuCursor > 0) menuCursor--;
      customDelay(2);
    }
    if (gb.buttons.pressed(BTN_DOWN)) {
      if (menuCursor < Length) menuCursor++;
      customDelay(2);
    }
    if (gb.buttons.pressed(BTN_A)) {
      Exit = true;
      menuSelected = menuCursor;
    }
    if (gb.buttons.pressed(BTN_B)) Exit = true;
  }
  return menuSelected;
}

There should be more security for the println function.
Obviously this menu is pretty boring so I'll be adding some things to it before the final product.