Switch to full style
Understanding the language, error messages, etc.
Post a reply

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

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:
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:
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

Re: gb.display.println() likes to fill screen with random ch

Wed Aug 26, 2015 2:08 am

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:
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?

Re: gb.display.println() likes to fill screen with random ch

Wed Aug 26, 2015 9:52 am

i have only uneducated guesses ;)
in
Code:
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:
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...

Re: gb.display.println() likes to fill screen with random ch

Wed Aug 26, 2015 8:49 pm

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!

Re: gb.display.println() likes to fill screen with random ch

Wed Sep 02, 2015 1:31 am

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:
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.
Post a reply