Index: apps/plugins/mazezam.c
===================================================================
--- apps/plugins/mazezam.c	(revision 12086)
+++ apps/plugins/mazezam.c	(working copy)
@@ -5,9 +5,8 @@
  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
  *                     \/            \/     \/    \/            \/
- * ### line of auto-generated stuff I don't understand ###
  *
- * Copyright (C) 2006 Malcolm Tyrrell
+ * Copyright (C) 2006-2007 Malcolm Tyrrell
  *
  * MazezaM - a Rockbox version of my ZX Spectrum game from 2002
  *
@@ -141,9 +140,14 @@
 /* The gap for the border around the heading in text pages. In fact, 2 is
  * really the only acceptable value.
  */
-#define MAZEZAM_MENU_BORDER        2
-#define MAZEZAM_EXTRA_LIFE         2 /* get an extra life every _ levels */
-#define MAZEZAM_START_LIVES        3 /* how many lives at game start */
+#define MAZEZAM_MENU_BORDER         2
+/* Extra lives now deprecated
+#define MAZEZAM_EXTRA_LIFE          2 * get an extra life every _ levels *
+*/
+/* Update the instructions if the CHECKPOINT macros are changed */
+#define MAZEZAM_FIRST_CHECKPOINT    3 /* The level at the first checkpoint */
+#define MAZEZAM_CHECKPOINT_INTERVAL 4 /* A checkpoint every _ levels */
+#define MAZEZAM_START_LIVES         3 /* how many lives at game start */
 
 #ifdef HAVE_LCD_COLOR
 #define MAZEZAM_HEADING_COLOR      LCD_RGBPACK(255,255,  0) /* Yellow      */
@@ -216,13 +220,16 @@
 };
 
 /* The number of help screens */
-#define MAZEZAM_NUM_HELP_PAGES   4
+#define MAZEZAM_NUM_HELP_PAGES   5
 
 /* The instruction screens */
 static const struct textpage help_page[] = {
     {4,{"Instructions","10 mazezams","bar your way","to freedom"}},
     {4,{"Instructions","Push the rows","left and right","to escape"}},
-    {4,{"Instructions","Press " MAZEZAM_RETRY_KEYNAME " to","retry a level","(lose 1 life)"}},
+    {4,{"Instructions","Press " MAZEZAM_RETRY_KEYNAME " to",
+          "retry a level","(lose 1 life)"}},
+    /* Must be kept consistent with level data and the CHECKPOINT macros */
+    {4,{"Instructions","Checkpoints","at levels","4 and 8"}},
     {4,{"Instructions","Press " MAZEZAM_QUIT_KEYNAME,"to quit","the game"}}
 };
 
@@ -235,7 +242,7 @@
 /* the text of the screen at the end of the game */
 static const struct textpage welldone_page = {
     3,
-    {"Well Done","You have","escaped",""}
+    {"Well Done","You have","escaped"}
 };
 
 /* the text of the screen asking if the user wants to
@@ -275,30 +282,25 @@
  * http://webpages.dcu.ie/~tyrrelma/MazezaM.
  */
 static const struct mazezam_level level_data[MAZEZAM_NUM_LEVELS] = {
-    {2,7,0,0,{" $  $"," $  $$",NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,
-                  NULL}},
-    {3,8,2,1,{"  $  $$$","  $ $ $"," $ $ $",NULL,NULL,NULL,NULL,NULL,NULL,
-                 NULL,NULL}},
+    {2,7,0,0,{" $  $"," $  $$"}},
+    {3,8,2,1,{"  $  $$$","  $ $ $"," $ $ $"}},
     {4,14,1,3,{" $$$$$ $$ $$","   $$  $$  $$","$$  $ $$ $$$",
-                 "   $$$$$$$$  $",NULL,NULL,NULL,NULL,NULL,NULL,NULL}},
-    {6,7,4,2,{"   $"," $$$$"," $$$ $$"," $ $ $"," $ $$","$ $$",
-                 NULL,NULL,NULL,NULL,NULL}},
+                 "   $$$$$$$$  $"}},
+    {6,7,4,2,{"   $"," $$$$"," $$$ $$"," $ $ $"," $ $$","$ $$"}},
     {6,13,0,0,{"   $$$$$","$ $$$$$  $$$"," $ $$$ $$$$",
-                 "$ $  $$$$$$$"," $$$ $   $$","$ $ $ $$  $",NULL,NULL,
-                 NULL,NULL,NULL}},
+                 "$ $  $$$$$$$"," $$$ $   $$","$ $ $ $$  $"}},
     {11,5,10,0,{"  $"," $ $$"," $$","$ $"," $ $"," $$$","$ $",
                  " $ $"," $ $","$ $$"," $"}},
     {7,16,0,6,{"      $$$$$$$","  $$$$ $$$$ $ $","$$ $$ $$$$$$ $ $",
                  "$      $ $"," $$$$$$$$$$$$$$"," $ $$    $ $$$",
-                 "  $   $$$     $$",NULL,NULL,NULL,NULL}},
+                 "  $   $$$     $$"}},
     {4,15,2,0,{" $$$$  $$$$  $$"," $ $$ $$ $ $$"," $ $$ $$$$ $$",
-                 " $ $$  $$$$  $",NULL,NULL,NULL,NULL,NULL,NULL,NULL}},
+                 " $ $$  $$$$  $"}},
     {7,9,6,2,{" $  $$$$"," $  $ $$"," $ $$$$ $","$ $$  $","  $   $$$",
-         " $$$$$$","  $",NULL,NULL,NULL,NULL}},
+         " $$$$$$","  $"}},
     {10,14,8,0,{"            $"," $$$$$$$$$$  $"," $$$       $$",
                  " $ $$$$$$$$ $"," $$$ $$$  $$$"," $$$   $  $$$",
-                 " $ $$$$$$$ $$"," $ $ $    $$$"," $$$$$$$$$$$$",
-                 "",NULL}}
+                 " $ $$$$$$$ $$"," $ $ $    $$$"," $$$$$$$$$$$$", ""}}
 };
 
 /* This is the data structure the game uses for managing levels */
@@ -794,6 +796,21 @@
     return state;
 }
 
+static void update_resume_data(struct resume_data *r, int level) {
+    if (level >= MAZEZAM_FIRST_CHECKPOINT) {
+        r->level = level - MAZEZAM_FIRST_CHECKPOINT;
+        r->level = (r->level / MAZEZAM_CHECKPOINT_INTERVAL)
+                       * MAZEZAM_CHECKPOINT_INTERVAL;
+        r->level = r->level + MAZEZAM_FIRST_CHECKPOINT;
+    }
+
+    /* The old resume game logic is designed to make
+     * players prove they can solve a level more than once
+    if (level > r->level + 1)
+        r->level += 1;
+     */
+}
+
 /* The loop which manages a full game of MazezaM */
 static enum game_state game_loop(struct resume_data *r) {
     enum game_state state = GAME_STATE_LOOPING;
@@ -807,8 +824,10 @@
         switch (level_loop(level,lives)) {
             case LEVEL_STATE_COMPLETED:
                 level += 1;
+                /* Extra lives now deprecated
                 if (!((level - r->level) % MAZEZAM_EXTRA_LIFE))
                     lives += 1;
+                */
                 break;
 
             case LEVEL_STATE_QUIT:
@@ -867,11 +886,9 @@
             break;
     }
 
-    /* This particular resume game logic is designed to make
-     * players prove they can solve a level more than once
+    /* Have we reached a checkpoint?
      */
-    if (level > r->level + 1)
-        r->level += 1;
+    update_resume_data(r,level);
 
     return state;
 }
