1010
Check-in [0719801f3f]
Not logged in
Public Repositories
mwm's Repositories

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Move help pages to PROGMEM to save RAM.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1:0719801f3f787beb368177d0b15018cecdb7b0cb
User & Date: mwm 2016-11-07 14:46:53
Context
2016-11-08
13:20
Fix a couple of places that you could use the menu/paging system to resume a done game with new pieces. check-in: 36b8d8890e user: mwm tags: trunk
2016-11-07
14:46
Move help pages to PROGMEM to save RAM. check-in: 0719801f3f user: mwm tags: trunk
13:22
Tweak that keys page some more. Move the init polling into the loop(). check-in: ad5306ec16 user: mwm tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to Tiny-1010.ino.

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
...
126
127
128
129
130
131
132

133
134
135
136

137
138
139

140
141
142

143
144
145
146
147
148
149
150


151
152
153


154

155
156
157
158
159
160
161
...
167
168
169
170
171
172
173
174

175
176
177
178
179
180
181
...
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
...
399
400
401
402
403
404
405

406
407
408
409
410
411
412
413
414
415
416
417
418
...
498
499
500
501
502
503
504
505

506
507
508
509
510

511
512
513
514
515
516
517
const byte BOARD_Y = 2;		// Top edge of the board.
const byte EMPTY = 0;		// Name of the empty tile.
const byte CLEAR = 1;		// WHITE tile for clearing.
const byte REMOVED = 255;	// A tile about to be emptied.

// Tile bitmaps. All 7x7, a 1-pixel border around a 5x5 color.
const byte TILE_SIZE = 7;			// Size of a color tile to draw.
const byte PROGMEM colors[][TILE_SIZE] = {
     {0x7F, 0x41, 0x41, 0x41, 0x41, 0x41, 0x7F},// EMPTY must be in position 0.
     {0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F},// 3x3 square, CLEAR in position 1.
     {0x7F, 0x41, 0x5D, 0x5D, 0x5D, 0x41, 0x7F},// 2x2 square
     {0x7F, 0x41, 0x41, 0x49, 0x41, 0x41, 0x7F},// 1x1 square
     {0x7F, 0x7F, 0x7F, 0x41, 0x7F, 0x7F, 0x7F},// vertical 5 long
     {0x7F, 0x41, 0x7F, 0x7F, 0x7F, 0x41, 0x7F},// vertical 4 long
     {0x7F, 0x41, 0x7F, 0x41, 0x7F, 0x41, 0x7F},// vertical 3 long
................................................................................
     {2, 2, fours[4]},
     {2, 2, fours[5]},
     {2, 2, fours[6]},
};


/* Help screens - 8 lines of 20 characters on each screen */

const char *help[] = {
     "  Help Navigation\n\nPage back and forth\nwith \33 and \32 as\n"
     "indicated in the\nupper corners. Exit\nwith \30. Press \32 now.",


     "      Game play\n\nSelect shapes to\nplace on empty\nsquares on the 10x10\n"
     "game board. Filling a\nrow or column clears\nit.",


     "       Scoring\n\nPlacing a shape\nscores one point for\neach block in the\n"
     "shape, and ten points\nfor each line\ncleared.",


     "  Buttons: B pauses!\n"
     " Selecting\336  Moving\n"
     "\30\31 changes\336 \33\31\30\32\n"
     "shape     \336 moves\n"
     "\32 selects \336 \33 at left\n"
     "to corner \336 deselects\n"
     "A autofits\336 A places\n"
     "then moves\336 shape",



     "        About\n\n1010 c Mike Meyer\nmwm@mired.org\n\nhttps://goo.gl/9EeMnN",
     NULL


};


// The game
typedef enum {INIT, MENU, DONE, SELECTING, MOVING, PAGING} game_state;
const byte WAIT_LEN = 3;

struct game_data {
     unsigned long high, score;
................................................................................

// Ephemeral values.
game_state state;		// Current game state
byte selected;	        	// substate indicator

const char *prompt;		// Menu prompt
#define PAUSED		"  Paused"
#define GAMEOVER 	"Game over!";

// The menu
enum {HELP, RESUME, NEW, KEYS, MENU_LAST};

/* Code to play the game. */
// Returns true if the shape is over clear tiles.
boolean
shape_clear(const shape *const s, const byte x, const byte y) {
................................................................................
     arduboy.setCursor(0, top);
     arduboy.print(msg);
}

void
draw_menu(void) {
     draw_msg(prompt);
     arduboy.print("\n\n\33 ");
     arduboy.print(selected == HELP ? " Help " :
                   selected == RESUME ? "Resume" :
                   selected == KEYS ? " Keys " :
                   selected == NEW ? "New" :
                   "BUG!");
     arduboy.print(" \32");
}

byte
draw_game(void) {
     byte can_place = 0;
     const shape *const s = &shapes[game.waiting[selected]];
     byte red, green, blue;

     red = green = blue = RGB_OFF;

     draw_board();
     arduboy.print("Score\n");
     arduboy.print(game.score);
     arduboy.setCursor(0, 44); 
     arduboy.print("High\n");
     arduboy.print(game.high);

     switch (state) {
     case INIT:
          arduboy.fillRect(0, 0, BOARD_X - 1, 64, 0);
          arduboy.setCursor(0, 16);
          draw_msg("1010 v0.95\n  by mwm\n\nPress A");
          break;
     case DONE:
................................................................................
          blue = RGB_ON;
          // Fall through
     case MENU:
          draw_menu();
          break;
     case PAGING:
          arduboy.clear();

          draw_msg(help[selected], 0);
          if (selected) {
               arduboy.setCursor(0, 0);
               arduboy.write('\33');
          }
          if (help[selected + 1] != NULL) {
               arduboy.setCursor(120, 0);
               arduboy.write('\32');
          }
          break;
     default:
          for (byte i = 0; i < WAIT_LEN; i += 1) {
               arduboy.setCursor(BLOCK_SIZE, (i + 3) * BLOCK_SIZE);
................................................................................
          } else if (arduboy.justPressed(RIGHT_BUTTON)) {
               selected = (selected + 1) % MENU_LAST;
          }
          break;
     case PAGING:
          if (arduboy.justPressed(LEFT_BUTTON) && selected)
              selected -= 1;
          else if (arduboy.justPressed(RIGHT_BUTTON) & help[selected + 1] != NULL)

               selected += 1;
          else if (arduboy.justPressed(UP_BUTTON)) {
               state = MENU;
               selected = HELP;
          }

     case SELECTING:
          if (arduboy.justPressed(UP_BUTTON))
               do {
                    if (selected)
                         selected -= 1;
                    else
                         selected = WAIT_LEN - 1;







|







 







>
|

|
<
>

|
<
>

|
<
>






|
|
>
>

<
<
>
>

>







 







|
>







 







|
|
|
|
|
|
|











|


|

<







 







>
|




|







 







|
>





>







28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
...
126
127
128
129
130
131
132
133
134
135
136

137
138
139

140
141
142

143
144
145
146
147
148
149
150
151
152
153
154


155
156
157
158
159
160
161
162
163
164
165
...
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
...
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395

396
397
398
399
400
401
402
...
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
...
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
const byte BOARD_Y = 2;		// Top edge of the board.
const byte EMPTY = 0;		// Name of the empty tile.
const byte CLEAR = 1;		// WHITE tile for clearing.
const byte REMOVED = 255;	// A tile about to be emptied.

// Tile bitmaps. All 7x7, a 1-pixel border around a 5x5 color.
const byte TILE_SIZE = 7;			// Size of a color tile to draw.
const byte colors[][TILE_SIZE] PROGMEM = {
     {0x7F, 0x41, 0x41, 0x41, 0x41, 0x41, 0x7F},// EMPTY must be in position 0.
     {0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F},// 3x3 square, CLEAR in position 1.
     {0x7F, 0x41, 0x5D, 0x5D, 0x5D, 0x41, 0x7F},// 2x2 square
     {0x7F, 0x41, 0x41, 0x49, 0x41, 0x41, 0x7F},// 1x1 square
     {0x7F, 0x7F, 0x7F, 0x41, 0x7F, 0x7F, 0x7F},// vertical 5 long
     {0x7F, 0x41, 0x7F, 0x7F, 0x7F, 0x41, 0x7F},// vertical 4 long
     {0x7F, 0x41, 0x7F, 0x41, 0x7F, 0x41, 0x7F},// vertical 3 long
................................................................................
     {2, 2, fours[4]},
     {2, 2, fours[5]},
     {2, 2, fours[6]},
};


/* Help screens - 8 lines of 20 characters on each screen */
char help_buffer[161];	// buffer for it.
const char nav_help[] PROGMEM =
     "  Help Navigation\n\nPage back and forth\nwith \33 and \32 as\n"
     "indicated in the\nupper corners. Exit\nwith \30. Press \32 now.";

const char play_help[] PROGMEM =
     "      Game play\n\nSelect shapes to\nplace on empty\nsquares on the 10x10\n"
     "game board. Filling a\nrow or column clears\nit.";

const char score_help[] PROGMEM =
     "       Scoring\n\nPlacing a shape\nscores one point for\neach block in the\n"
     "shape, and ten points\nfor each line\ncleared.";

const char key_help[] PROGMEM =
     "  Buttons: B pauses!\n"
     " Selecting\336  Moving\n"
     "\30\31 changes\336 \33\31\30\32\n"
     "shape     \336 moves\n"
     "\32 selects \336 \33 at left\n"
     "to corner \336 deselects\n"
     "A selects \336 A places\n"
     "& autofits\336 shape";
const char about[] PROGMEM = 
     "        About\n\n1010 c Mike Meyer\nmwm@mired.org\n\nhttps://goo.gl/9EeMnN";



const char *const help[] PROGMEM = {
     nav_help, play_help, score_help, key_help, about
};


// The game
typedef enum {INIT, MENU, DONE, SELECTING, MOVING, PAGING} game_state;
const byte WAIT_LEN = 3;

struct game_data {
     unsigned long high, score;
................................................................................

// Ephemeral values.
game_state state;		// Current game state
byte selected;	        	// substate indicator

const char *prompt;		// Menu prompt
#define PAUSED		"  Paused"
#define GAMEOVER	"Game over!"

// The menu
enum {HELP, RESUME, NEW, KEYS, MENU_LAST};

/* Code to play the game. */
// Returns true if the shape is over clear tiles.
boolean
shape_clear(const shape *const s, const byte x, const byte y) {
................................................................................
     arduboy.setCursor(0, top);
     arduboy.print(msg);
}

void
draw_menu(void) {
     draw_msg(prompt);
     arduboy.print(F("\n\n\33 "));
     arduboy.print(selected == HELP ? F(" Help ") :
                   selected == RESUME ? F("Resume") :
                   selected == KEYS ? F(" Keys ") :
                   selected == NEW ? F("New") :
                   F("BUG!"));
     arduboy.print(F(" \32"));
}

byte
draw_game(void) {
     byte can_place = 0;
     const shape *const s = &shapes[game.waiting[selected]];
     byte red, green, blue;

     red = green = blue = RGB_OFF;

     draw_board();
     arduboy.print(F("Score\n"));
     arduboy.print(game.score);
     arduboy.setCursor(0, 44); 
     arduboy.print(F("High\n"));
     arduboy.print(game.high);

     switch (state) {
     case INIT:
          arduboy.fillRect(0, 0, BOARD_X - 1, 64, 0);
          arduboy.setCursor(0, 16);
          draw_msg("1010 v0.95\n  by mwm\n\nPress A");
          break;
     case DONE:
................................................................................
          blue = RGB_ON;
          // Fall through
     case MENU:
          draw_menu();
          break;
     case PAGING:
          arduboy.clear();
          strcpy_P(help_buffer, (char *)pgm_read_word(&(help[selected])));
          draw_msg(help_buffer, 0);
          if (selected) {
               arduboy.setCursor(0, 0);
               arduboy.write('\33');
          }
          if (selected < sizeof(help) / sizeof(char *) - 1) {
               arduboy.setCursor(120, 0);
               arduboy.write('\32');
          }
          break;
     default:
          for (byte i = 0; i < WAIT_LEN; i += 1) {
               arduboy.setCursor(BLOCK_SIZE, (i + 3) * BLOCK_SIZE);
................................................................................
          } else if (arduboy.justPressed(RIGHT_BUTTON)) {
               selected = (selected + 1) % MENU_LAST;
          }
          break;
     case PAGING:
          if (arduboy.justPressed(LEFT_BUTTON) && selected)
              selected -= 1;
          else if (arduboy.justPressed(RIGHT_BUTTON)
                   && selected < sizeof(help) / sizeof(char *) - 1)
               selected += 1;
          else if (arduboy.justPressed(UP_BUTTON)) {
               state = MENU;
               selected = HELP;
          }
          break;
     case SELECTING:
          if (arduboy.justPressed(UP_BUTTON))
               do {
                    if (selected)
                         selected -= 1;
                    else
                         selected = WAIT_LEN - 1;