STARTREK for Arduboy

To @Dreamer3.

I think so too!

I have a question for teacher @Pharap about FlashStringDemo.

Q1)
I used the sprintf statement to display "THERE ARE %d BASES." If I use FlashStringHelpler,

  arduboy.print(readFlashStringPointer(&strings[n]));
  arduboy.print( totalBase );
  arduboy.print(readFlashStringPointer(&strings[n+1]));

Do I do this? Or is there another way?

Q2)
When I displayed the message, I applied the effect of a typewriter-type sentence.

  for( int i=0; i < strlen( buf ); i++){
    font3x5.print( buf[i] );
    arduboy.display();
    delay(100);
  }

I used buf[i] to retrieve the i-th character in the buffer. How do I extract the i-th character when using FlashStringHelper?

If you have time, please let me know.

1 Like

sprintfは非効率。

はい。

You could try this:

// Helper function
template<typename Type>
Print & operator <<(Print & printer, const Type & value)
{
	printer.print(value);
	return printer;
}

void example()
{
	arduboy << readFlashStringPointer(&strings[n])
	<< totalBase << readFlashStringPointer(&strings[n + 1]);
}

(This is what std::cout does.)


Hrm… もんだいです。それは可能です、でも…

Even if you can ‘retrieve the i-th character’,
the typewriter effect will be difficult for ‘total kingons’…

だから…

Add this class:

#include "FlashStringHelper.h"

class SlowPrinter
{
private:
  bool quick = false;
  
  void checkDelay() {
    if(!quick) {
      delay(100);
      arduboy.pollButtons();
      if (arduboy.justPressed(A_BUTTON)) {
        quick = true;
      }
    }
  }
  
public:
  void slowPrint(FlashStringHelper message) {
    const char * pointer = reinterpret_cast<const char *>(message);

    while(true) {
      char c = pgm_read_byte(pointer);
      ++pointer;
      
      if(c == '\0')
        break;
        
      font3x5.print(c);
      arduboy.display();

      checkDelay();
    }
  }

  void slowPrint(uint8_t value) {  
    if(value == 0) {
      font3x5.print('0');
      arduboy.display();
      checkDelay();
      return;
    }
  
    uint8_t digits[3];

    for(uint8_t i = 0; i < 3; ++i) {
      digits[(3 - 1) - i] = (value % 10);
      value /= 10;
    }
    
    for(uint8_t i = 0; i < 3; ++i) {
      if(digits[i] > 0) {
        printDigit(digits[i]);
        arduboy.display();
      }

      checkDelay();
    }
  }
  
  void printDigit(uint8_t digit) {
    static constexpr char digits[] PROGMEM {
      '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
    };

    font3x5.print(static_cast<char>(pgm_read_byte(&digits[digit & 0x0F])));
  }
};

And then:

void toEnterprise( int mes ){
  arduboy.clear();
  font3x5.setTextColor(WHITE);
  
  SlowPrinter printer;
  font3x5.setCursor(12,7);
  if(mes == 1){
    printer.slowPrint(readFlashStringPointer(&string_table[ /*Klingon message*/ ]));
    printer.slowPrint(totalKlingon);
    printer.slowPrint(readFlashStringPointer(&string_table[ /*base message*/ ]));
    printer.slowPrint(totalBases);
  } else {
    printer.slowPrintMessage(readFlashStringPointer(&string_table[ 4 + mes ]));
  }
  
  while(true){
    arduboy.pollButtons();
    if (arduboy.justPressed(A_BUTTON)) {
      break;
    }
  }
}

There are better ways, but I don’t want to make the code too complicated in case you can’t understand it.

わかりますか?
わかりませんか?

1 Like

To @Pharap.
Thank you very much for a quick and easy-to-understand reply!

Yes. Just by commenting out one line of sprintf(...), the size of hex is reduced by 1502 bytes.

なるほど。I can use templates like this. The template is amazing!

なるほど!

  FlashStringHelper mes;
  const char * pointer;
  char c;
    ...
  mes = readFlashStringPointer(&strings[0]);
  pointer = reinterpret_cast<const char *>(mes) + i;
  c = pgm_read_byte(pointer);
    ...

First, take the address where the message is stored from the table…
Next, move the pointer by the number of characters from there…
Finally, the data indicated by the pointer is read using pgm_read_byte(...).

とても良く、分かりました! A very easy to understand description!
I also learned how to use classes to change the handling of strings and numbers.
class and template … I feel like I have entered a new world!

1 Like

sprintf is NOT your friend on tiny embedded hardware.

1 Like

To @Dreamer3.
I really think so. 1502 bytes are 5% of all the sketches I can write!

1 Like

はい、きっちり。(Exactly.)

でも、これも。

FlashStringHelper mes = readFlashStringPointer(&strings[0]);
const char * pointer = reinterpret_cast<const char *>(mes);
char c = pgm_read_byte(&pointer[i])
  1. Read address from strings
  2. Convert FlashStringHelper to const char *
  3. Index pointer, read from progmem pointer.

Note:

  • &pointer[i] == (pointer + i)
  • pointer[i] == *(pointer + i)
    • でも、*pointer reads RAM, pgm_read_byte(pointer) reads progmem, so pointer[i] for RAM and pgm_read_byte(&pointer[i]) for progmem.

はい、classとtemplateの力はすごいですよね。

1 Like

To @Pharap.

一歩前進。–One step to forward.

なるほど。I want to make another game. :smile:

1 Like

I re-wrote the program using the class and the FlashStringHelper technique taught by @Pharap . There is no change in the content of the game. There are a few changes to the appearance of alerts.

1 Like

Can we fix this thread so you can play the game in the first message like in so many other of these threads?

1 Like

To @Dreamer3.
Thanks for your suggestion.
Untitled
Maybe this is it?
What should I do?

Just upload your latest .hex file directly in your initial post and the forum will do the rest.

2 Likes

I have edited the main post:

  • The GitHub link is fixed (tag beta was deleted)
  • The latest .hex has been uploaded (from releases)
    • A date has been added to indicate when it was updated
  • The link to the most recent version has been kept

よくやった 。

はい、大きい歩。

良い試み、でも「One step forward」。
「to <旅先>」、でも「forward」は旅先じゃないです。「forward」は方向。
(‘to <destination>’, but ‘forward’ is not a destination. ‘Forward’ is a direction.)

それはいいよ。でも、このゲームを仕上がったろーか?

(Is this game finished/completed?)

3 Likes

Thank you, @Dreamer3, @Vampirics and @Pharap!

Is this something I can do if I study?

Yay. :laughing:

Ah… I made a mistake again. It is difficult for me to use English.

The program I referred to is a basic program with about 600 lines. In this program, when a command was entered numerically, the result was displayed as an ASCII character and scrolled. It’s the current program that makes it a fixed screen, organizes commands, and adds new features. I am wondering where to set goals.

  • Generate more stars and structures?
  • Make enemies smarter?
  • Including bitmaps and lots of animations? etc.etc.etc.

If I change too much, it will no longer be “STARTREK”. Hobby programs are difficult to finish. (So, in me, “Rogue” is not over yet. :cry:)

To everyone. I forgot to license this program. I have updated the repository on GitHub. The license for this program is based on the MIT license.

1 Like

Is or “is based on”? If it’s not vanilla MIT it probably shouldn’t suggest so at the top in the title.

1 Like

鉛筆のアイコンは「エディット」:

PencilIcon

私も。日本語は上手じゃない。
でも、がんばれね。私も。私はがんばる。

Hrm… それは変です。I can’t imagine what it does.

なぞなぞだね。

いいえ、それは「BlueMaxのSTARTREK」でしょう。
でも、それは良いでしょうね。

よくやった 。Good job for remembering. I had forgotten.


It definitely is 100% pure MIT.

It doesn’t take long to check, you can just run a diff over the licence text and a copy of the MIT licence.

1 Like

To @Dreamer3.
Sorry, and thank you.
The license for this program is the MIT license.

1 Like

To @Pharap.

I found it in YOUTUBE.

I got an issue on GitHub.

1 Like

ああ、なるほど。

「コマンドラインインターフェイス」。

英語で、‘Command Line Interface’/‘CLI’.
Also ‘console’ (コンソール) or ‘terminal’ (ターミナル).

なるほど。「yyyc514」は @Dreamer3 です。

1 Like

To @Pharap.

Yes. Command Line Interface. The original seems to have been written in BASIC on a minicomputer in 1971.

Oh really. Thank you for teaching me.

1 Like

If I was going to start reporting bugs I could probably come up with a list.

  • Should viewing damage really cause a day to pass?
  • Ditto for other things like just viewing the map, etc.
  • Maybe that was part of the original game, but feels very strange.
  • There should be some way to cancel things like firing a torpedo or phasers if you change your mind.