blob: 0f0b90f1ed130b5b9a9adb9205dfe26653f0b832 [file] [log] [blame]
Robert Hakd58ab782002-06-16 23:24:22 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
Björn Stenberg7826fc32002-06-20 10:49:15 +00008 * $Id$
Robert Hakd58ab782002-06-16 23:24:22 +00009 *
10 * Copyright (C) 2002 Eric Linenberg
11 *
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
14 *
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
17 *
18 ****************************************************************************/
19
20#include "config.h"
Daniel Stenberg6e881b42002-09-06 07:35:40 +000021#include "options.h"
Robert Hak8f11dc02002-10-29 10:45:29 +000022
Robert Hak1bcdb232002-08-31 23:41:17 +000023#ifdef USE_GAMES
Robert Hake0248c52002-08-31 22:55:40 +000024
25#include <sprintf.h>
Robert Hakd58ab782002-06-16 23:24:22 +000026#include "sokoban.h"
27#include "lcd.h"
28#include "button.h"
29#include "kernel.h"
Daniel Stenbergb2850762002-08-23 12:32:52 +000030#include "menu.h"
Björn Stenbergb1b8bd42002-09-24 17:22:12 +000031#include "screens.h"
Robert Hak8f11dc02002-10-29 10:45:29 +000032#include "font.h"
Robert Hakd58ab782002-06-16 23:24:22 +000033
Robert Hak1df1e512002-10-19 12:06:16 +000034#include "sokoban_levels.h"
35
Robert Hakd58ab782002-06-16 23:24:22 +000036#ifdef SIMULATOR
37#include <stdio.h>
38#endif
39#include <string.h>
Björn Stenberg505eca72002-09-18 14:08:05 +000040#include "lang.h"
Robert Hakd58ab782002-06-16 23:24:22 +000041#define SOKOBAN_TITLE "Sokoban"
42#define SOKOBAN_TITLE_FONT 2
Björn Stenberg7826fc32002-06-20 10:49:15 +000043#define NUM_LEVELS sizeof(levels)/320
Robert Hakd58ab782002-06-16 23:24:22 +000044
Björn Stenbergb1b8bd42002-09-24 17:22:12 +000045static void load_level(int);
46static void update_screen(void);
47static bool sokoban_loop(void);
Eric Linenberg16576ef2003-01-16 05:44:00 +000048static void copy_current_state_to_undo(void);
49static void copy_current_undo_to_state(void);
Björn Stenbergb1b8bd42002-09-24 17:22:12 +000050
Björn Stenberg7826fc32002-06-20 10:49:15 +000051static char board[16][20];
Eric Linenberg16576ef2003-01-16 05:44:00 +000052static char undo_board[16][20];
Björn Stenberg7826fc32002-06-20 10:49:15 +000053static int current_level=0;
Eric Linenberg16576ef2003-01-16 05:44:00 +000054static int undo_current_level=0;
Björn Stenberg7826fc32002-06-20 10:49:15 +000055static int moves=0;
Eric Linenberg16576ef2003-01-16 05:44:00 +000056static int undo_moves=0;
Björn Stenberg7826fc32002-06-20 10:49:15 +000057static int row=0;
Eric Linenberg16576ef2003-01-16 05:44:00 +000058static int undo_row=0;
Björn Stenberg7826fc32002-06-20 10:49:15 +000059static int col=0;
Eric Linenberg16576ef2003-01-16 05:44:00 +000060static int undo_col=0;
Björn Stenberg7826fc32002-06-20 10:49:15 +000061static int boxes_to_go=0;
Eric Linenberg16576ef2003-01-16 05:44:00 +000062static int undo_boxes_to_go=0;
Robert Hak1df1e512002-10-19 12:06:16 +000063static char current_spot= ' ';
Eric Linenberg16576ef2003-01-16 05:44:00 +000064static char undo_current_spot=' ';
65
66
Eric Linenberg16576ef2003-01-16 05:44:00 +000067static void copy_current_state_to_undo(void) {
68 int a = 0;
69 int b = 0;
70
71 for (a=0 ; a<16 ; a++) {
72 for (b=0; b<16 ; b++) {
73 undo_board[a][b] = board[a][b];
74 }
75 }
76 undo_current_level = current_level;
77 undo_moves = moves;
78 undo_row = row;
79 undo_col = col;
80 undo_boxes_to_go = boxes_to_go;
81 undo_current_spot = current_spot;
82
83 return;
84}
85
86static void copy_current_undo_to_state(void) {
87 int a = 0;
88 int b = 0;
89
90 for (a=0 ; a<16 ; a++) {
91 for (b=0; b<16 ; b++) {
92 board[a][b] = undo_board[a][b];
93 }
94 }
95 current_level = undo_current_level;
96 moves = undo_moves-1;
97 row = undo_row;
98 col = undo_col;
99 boxes_to_go = undo_boxes_to_go;
100 current_spot = undo_current_spot;
101 return;
102}
Robert Hakd58ab782002-06-16 23:24:22 +0000103
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000104static void load_level (int level_to_load) {
Robert Hakd58ab782002-06-16 23:24:22 +0000105 int a = 0;
106 int b = 0;
107 int c = 0;
Robert Hak1df1e512002-10-19 12:06:16 +0000108 current_spot=' ';
Eric Linenberg36923362002-06-19 14:26:41 +0000109 boxes_to_go = 0;
Robert Hakd58ab782002-06-16 23:24:22 +0000110 /* load level into board */
111 /* get to the current level in the level array */
Robert Hakd58ab782002-06-16 23:24:22 +0000112
113 for(b=0 ; b<16 ; b++) {
114 for (c=0 ; c<20 ; c++) {
Robert Hak1df1e512002-10-19 12:06:16 +0000115 board[b][c] = levels[level_to_load][a]/* - '0'*/;
Robert Hakd58ab782002-06-16 23:24:22 +0000116 a++;
Robert Hak1df1e512002-10-19 12:06:16 +0000117 if (board[b][c]=='@') {
Robert Hakd58ab782002-06-16 23:24:22 +0000118 row = b;
119 col = c;
120 }
Robert Hak1df1e512002-10-19 12:06:16 +0000121 if (board[b][c]=='.')
Robert Hakd58ab782002-06-16 23:24:22 +0000122 boxes_to_go++;
123 }
124 }
125 return;
126}
127
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000128static void update_screen(void) {
Robert Hakd58ab782002-06-16 23:24:22 +0000129 int b = 0;
130 int c = 0;
131 char s[25];
132
133 /* load the board to the screen */
134 for(b=0 ; b<16 ; b++) {
135 for (c=0 ; c<20 ; c++) {
Björn Stenberg7826fc32002-06-20 10:49:15 +0000136 switch ( board[b][c] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000137 case 'X': /* this is a black space */
Markus Braunaad11162002-08-28 14:22:40 +0000138 lcd_drawrect (c*4, b*4, 4, 4);
139 lcd_drawrect (c*4+1, b*4+1, 2, 2);
Björn Stenberg7826fc32002-06-20 10:49:15 +0000140 break;
141
Robert Hak1df1e512002-10-19 12:06:16 +0000142 case '#': /* this is a wall */
Björn Stenberg7826fc32002-06-20 10:49:15 +0000143 lcd_drawpixel (c*4, b*4);
144 lcd_drawpixel (c*4+2, b*4);
145 lcd_drawpixel (c*4+1, b*4+1);
146 lcd_drawpixel (c*4+3, b*4+1);
147 lcd_drawpixel (c*4, b*4+2);
148 lcd_drawpixel (c*4+2, b*4+2);
149 lcd_drawpixel (c*4+1, b*4+3);
150 lcd_drawpixel (c*4+3, b*4+3);
151 break;
152
Robert Hak1df1e512002-10-19 12:06:16 +0000153 case '.': /* this is a home location */
Markus Braunaad11162002-08-28 14:22:40 +0000154 lcd_drawrect (c*4+1, b*4+1, 2, 2);
Björn Stenberg7826fc32002-06-20 10:49:15 +0000155 break;
156
Robert Hak1df1e512002-10-19 12:06:16 +0000157 case '$': /* this is a box */
Markus Braunaad11162002-08-28 14:22:40 +0000158 lcd_drawrect (c*4, b*4, 4, 4);
Björn Stenberg7826fc32002-06-20 10:49:15 +0000159 break;
160
Robert Hak1df1e512002-10-19 12:06:16 +0000161 case '@': /* this is you */
Björn Stenberg7826fc32002-06-20 10:49:15 +0000162 lcd_drawline (c*4+1, b*4, c*4+2, b*4);
163 lcd_drawline (c*4, b*4+1, c*4+3, b*4+1);
164 lcd_drawline (c*4+1, b*4+2, c*4+2, b*4+2);
165 lcd_drawpixel (c*4, b*4+3);
166 lcd_drawpixel (c*4+3, b*4+3);
167 break;
168
Robert Hak1df1e512002-10-19 12:06:16 +0000169 case '%': /* this is a box on a home spot */
Markus Braunaad11162002-08-28 14:22:40 +0000170 lcd_drawrect (c*4, b*4, 4, 4);
171 lcd_drawrect (c*4+1, b*4+1, 2, 2);
Björn Stenberg7826fc32002-06-20 10:49:15 +0000172 break;
Robert Hakd58ab782002-06-16 23:24:22 +0000173 }
Robert Hakd58ab782002-06-16 23:24:22 +0000174 }
175 }
176
177
178 snprintf (s, sizeof(s), "%d", current_level+1);
Björn Stenberga4c3b032002-09-24 18:04:15 +0000179 lcd_putsxy (86, 22, s);
Robert Hakd58ab782002-06-16 23:24:22 +0000180 snprintf (s, sizeof(s), "%d", moves);
Björn Stenberga4c3b032002-09-24 18:04:15 +0000181 lcd_putsxy (86, 54, s);
Robert Hakd58ab782002-06-16 23:24:22 +0000182
Markus Braunaad11162002-08-28 14:22:40 +0000183 lcd_drawrect (80,0,32,32);
184 lcd_drawrect (80,32,32,64);
Björn Stenberga4c3b032002-09-24 18:04:15 +0000185 lcd_putsxy (81, 10, str(LANG_SOKOBAN_LEVEL));
186 lcd_putsxy (81, 42, str(LANG_SOKOBAN_MOVE));
Robert Hakd58ab782002-06-16 23:24:22 +0000187 /* print out the screen */
188 lcd_update();
189}
190
191
192
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000193static bool sokoban_loop(void)
194{
Robert Hakd58ab782002-06-16 23:24:22 +0000195 int ii = 0;
Robert Hakd58ab782002-06-16 23:24:22 +0000196 moves = 0;
197 current_level = 0;
198 load_level(current_level);
199 update_screen();
200
201 while(1) {
Eric Linenberg16576ef2003-01-16 05:44:00 +0000202
Björn Stenbergc40ac322002-06-24 11:02:18 +0000203 bool idle = false;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000204 switch ( button_get(true) ) {
Björn Stenberg7826fc32002-06-20 10:49:15 +0000205 case BUTTON_OFF:
206 /* get out of here */
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000207 return false;
Robert Hakd58ab782002-06-16 23:24:22 +0000208
Björn Stenberg7826fc32002-06-20 10:49:15 +0000209 case BUTTON_F3:
210 /* increase level */
211 boxes_to_go=0;
Björn Stenbergc40ac322002-06-24 11:02:18 +0000212 idle=true;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000213 break;
Robert Hakd58ab782002-06-16 23:24:22 +0000214
Eric Linenberg16576ef2003-01-16 05:44:00 +0000215 case BUTTON_ON:
216 /* this is UNDO */
217 copy_current_undo_to_state();
218 break;
219
Björn Stenberg7826fc32002-06-20 10:49:15 +0000220 case BUTTON_F2:
221 /* same level */
222 load_level(current_level);
Björn Stenberg7826fc32002-06-20 10:49:15 +0000223 moves=0;
Björn Stenbergc40ac322002-06-24 11:02:18 +0000224 idle=true;
Eric Linenberg1d1c9592002-06-25 14:43:16 +0000225 load_level(current_level);
226 lcd_clear_display();
227 update_screen();
Eric Linenberged693902003-01-16 14:50:34 +0000228 copy_current_state_to_undo();
229 copy_current_undo_to_state();
Björn Stenberg7826fc32002-06-20 10:49:15 +0000230 break;
Eric Linenberg36923362002-06-19 14:26:41 +0000231
Björn Stenberg7826fc32002-06-20 10:49:15 +0000232 case BUTTON_F1:
Eric Linenberged693902003-01-16 14:50:34 +0000233
Björn Stenberg7826fc32002-06-20 10:49:15 +0000234 /* previous level */
Björn Stenbergc40ac322002-06-24 11:02:18 +0000235 if (current_level)
Björn Stenberg7826fc32002-06-20 10:49:15 +0000236 current_level--;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000237 load_level(current_level);
Björn Stenberg7826fc32002-06-20 10:49:15 +0000238 moves=0;
Björn Stenbergc40ac322002-06-24 11:02:18 +0000239 idle=true;
Eric Linenberg1d1c9592002-06-25 14:43:16 +0000240 load_level(current_level);
241 lcd_clear_display();
242 update_screen();
Eric Linenberged693902003-01-16 14:50:34 +0000243 copy_current_state_to_undo();
244 copy_current_undo_to_state();
Björn Stenberg7826fc32002-06-20 10:49:15 +0000245 break;
246
247 case BUTTON_LEFT:
Eric Linenberg16576ef2003-01-16 05:44:00 +0000248 copy_current_state_to_undo();
Björn Stenberg7826fc32002-06-20 10:49:15 +0000249 switch ( board[row][col-1] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000250 case ' ': /* if it is a blank spot */
251 board[row][col-1]='@';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000252 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000253 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000254 break;
255
Robert Hak1df1e512002-10-19 12:06:16 +0000256 case '.': /* if it is a home spot */
257 board[row][col-1]='@';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000258 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000259 current_spot='.';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000260 break;
261
Robert Hak1df1e512002-10-19 12:06:16 +0000262 case '$':
Björn Stenberg7826fc32002-06-20 10:49:15 +0000263 switch ( board[row][col-2] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000264 case ' ': /* if we are going from blank to blank */
Björn Stenberg7826fc32002-06-20 10:49:15 +0000265 board[row][col-2]=board[row][col-1];
266 board[row][col-1]=board[row][col];
267 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000268 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000269 break;
270
Robert Hak1df1e512002-10-19 12:06:16 +0000271 case '.': /* if we are going from a blank to home */
272 board[row][col-2]='%';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000273 board[row][col-1]=board[row][col];
274 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000275 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000276 boxes_to_go--;
Björn Stenbergc40ac322002-06-24 11:02:18 +0000277 break;
278
279 default:
280 idle = true;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000281 break;
282 }
283 break;
284
Robert Hak1df1e512002-10-19 12:06:16 +0000285 case '%':
Björn Stenberg7826fc32002-06-20 10:49:15 +0000286 switch ( board[row][col-2] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000287 case ' ': /* we are going from a home to a blank */
288 board[row][col-2]='$';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000289 board[row][col-1]=board[row][col];
290 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000291 current_spot='.';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000292 boxes_to_go++;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000293 break;
294
Robert Hak1df1e512002-10-19 12:06:16 +0000295 case '.': /* if we are going from a home to home */
296 board[row][col-2]='%';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000297 board[row][col-1]=board[row][col];
298 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000299 current_spot='.';
Björn Stenbergc40ac322002-06-24 11:02:18 +0000300 break;
301
302 default:
303 idle = true;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000304 break;
305 }
Björn Stenbergc40ac322002-06-24 11:02:18 +0000306 break;
307
308 default:
309 idle = true;
310 break;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000311 }
Björn Stenbergc40ac322002-06-24 11:02:18 +0000312 if (!idle)
313 col--;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000314 break;
315
316 case BUTTON_RIGHT: /* if it is a blank spot */
Eric Linenberg16576ef2003-01-16 05:44:00 +0000317 copy_current_state_to_undo();
Björn Stenberg7826fc32002-06-20 10:49:15 +0000318 switch ( board[row][col+1] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000319 case ' ':
320 board[row][col+1]='@';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000321 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000322 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000323 break;
324
Robert Hak1df1e512002-10-19 12:06:16 +0000325 case '.': /* if it is a home spot */
326 board[row][col+1]='@';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000327 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000328 current_spot='.';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000329 break;
330
Robert Hak1df1e512002-10-19 12:06:16 +0000331 case '$':
Björn Stenberg7826fc32002-06-20 10:49:15 +0000332 switch ( board[row][col+2] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000333 case ' ': /* if we are going from blank to blank */
Björn Stenberg7826fc32002-06-20 10:49:15 +0000334 board[row][col+2]=board[row][col+1];
335 board[row][col+1]=board[row][col];
336 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000337 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000338 break;
339
Robert Hak1df1e512002-10-19 12:06:16 +0000340 case '.': /* if we are going from a blank to home */
341 board[row][col+2]='%';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000342 board[row][col+1]=board[row][col];
343 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000344 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000345 boxes_to_go--;
Björn Stenbergc40ac322002-06-24 11:02:18 +0000346 break;
347
348 default:
349 idle = true;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000350 break;
351 }
352 break;
353
Robert Hak1df1e512002-10-19 12:06:16 +0000354 case '%':
Björn Stenberg7826fc32002-06-20 10:49:15 +0000355 switch ( board[row][col+2] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000356 case ' ': /* we are going from a home to a blank */
357 board[row][col+2]='$';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000358 board[row][col+1]=board[row][col];
359 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000360 current_spot='.';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000361 boxes_to_go++;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000362 break;
363
Robert Hak1df1e512002-10-19 12:06:16 +0000364 case '.':
365 board[row][col+2]='%';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000366 board[row][col+1]=board[row][col];
367 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000368 current_spot='.';
Björn Stenbergc40ac322002-06-24 11:02:18 +0000369 break;
370
371 default:
372 idle = true;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000373 break;
374 }
375 break;
Björn Stenbergc40ac322002-06-24 11:02:18 +0000376
377 default:
378 idle = true;
379 break;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000380 }
Björn Stenbergc40ac322002-06-24 11:02:18 +0000381 if (!idle)
382 col++;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000383 break;
384
385 case BUTTON_UP:
Eric Linenberg16576ef2003-01-16 05:44:00 +0000386 copy_current_state_to_undo();
Björn Stenberg7826fc32002-06-20 10:49:15 +0000387 switch ( board[row-1][col] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000388 case ' ': /* if it is a blank spot */
389 board[row-1][col]='@';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000390 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000391 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000392 break;
393
Robert Hak1df1e512002-10-19 12:06:16 +0000394 case '.': /* if it is a home spot */
395 board[row-1][col]='@';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000396 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000397 current_spot='.';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000398 break;
399
Robert Hak1df1e512002-10-19 12:06:16 +0000400 case '$':
Björn Stenberg7826fc32002-06-20 10:49:15 +0000401 switch ( board[row-2][col] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000402 case ' ': /* if we are going from blank to blank */
Björn Stenberg7826fc32002-06-20 10:49:15 +0000403 board[row-2][col]=board[row-1][col];
404 board[row-1][col]=board[row][col];
405 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000406 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000407 break;
408
Robert Hak1df1e512002-10-19 12:06:16 +0000409 case '.': /* if we are going from a blank to home */
410 board[row-2][col]='%';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000411 board[row-1][col]=board[row][col];
412 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000413 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000414 boxes_to_go--;
Björn Stenbergc40ac322002-06-24 11:02:18 +0000415 break;
416
417 default:
418 idle = true;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000419 break;
420 }
421 break;
422
Robert Hak1df1e512002-10-19 12:06:16 +0000423 case '%':
Björn Stenberg7826fc32002-06-20 10:49:15 +0000424 switch ( board[row-2][col] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000425 case ' ': /* we are going from a home to a blank */
426 board[row-2][col]='$';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000427 board[row-1][col]=board[row][col];
428 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000429 current_spot='.';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000430 boxes_to_go++;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000431 break;
432
Robert Hak1df1e512002-10-19 12:06:16 +0000433 case '.': /* if we are going from a home to home */
434 board[row-2][col]='%';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000435 board[row-1][col]=board[row][col];
436 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000437 current_spot='.';
Björn Stenbergc40ac322002-06-24 11:02:18 +0000438 break;
439
440 default:
441 idle = true;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000442 break;
443 }
444 break;
Björn Stenbergc40ac322002-06-24 11:02:18 +0000445
446 default:
447 idle = true;
448 break;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000449 }
Björn Stenbergc40ac322002-06-24 11:02:18 +0000450 if (!idle)
451 row--;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000452 break;
453
454 case BUTTON_DOWN:
Eric Linenberg16576ef2003-01-16 05:44:00 +0000455 copy_current_state_to_undo();
Björn Stenberg7826fc32002-06-20 10:49:15 +0000456 switch ( board[row+1][col] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000457 case ' ': /* if it is a blank spot */
458 board[row+1][col]='@';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000459 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000460 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000461 break;
462
Robert Hak1df1e512002-10-19 12:06:16 +0000463 case '.': /* if it is a home spot */
464 board[row+1][col]='@';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000465 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000466 current_spot='.';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000467 break;
468
Robert Hak1df1e512002-10-19 12:06:16 +0000469 case '$':
Björn Stenberg7826fc32002-06-20 10:49:15 +0000470 switch ( board[row+2][col] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000471 case ' ': /* if we are going from blank to blank */
Björn Stenberg7826fc32002-06-20 10:49:15 +0000472 board[row+2][col]=board[row+1][col];
473 board[row+1][col]=board[row][col];
474 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000475 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000476 break;
477
Robert Hak1df1e512002-10-19 12:06:16 +0000478 case '.': /* if we are going from a blank to home */
479 board[row+2][col]='%';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000480 board[row+1][col]=board[row][col];
481 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000482 current_spot=' ';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000483 boxes_to_go--;
Björn Stenbergc40ac322002-06-24 11:02:18 +0000484 break;
485
486 default:
487 idle = true;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000488 break;
489 }
490 break;
491
Robert Hak1df1e512002-10-19 12:06:16 +0000492 case '%':
Björn Stenberg7826fc32002-06-20 10:49:15 +0000493 switch ( board[row+2][col] ) {
Robert Hak1df1e512002-10-19 12:06:16 +0000494 case ' ': /* we are going from a home to a blank */
495 board[row+2][col]='$';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000496 board[row+1][col]=board[row][col];
497 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000498 current_spot='.';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000499 boxes_to_go++;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000500 break;
501
Robert Hak1df1e512002-10-19 12:06:16 +0000502 case '.': /* if we are going from a home to home */
503 board[row+2][col]='%';
Björn Stenberg7826fc32002-06-20 10:49:15 +0000504 board[row+1][col]=board[row][col];
505 board[row][col]=current_spot;
Robert Hak1df1e512002-10-19 12:06:16 +0000506 current_spot='.';
Björn Stenbergc40ac322002-06-24 11:02:18 +0000507 break;
508
509 default:
510 idle = true;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000511 break;
512 }
Björn Stenbergc40ac322002-06-24 11:02:18 +0000513 break;
514
515 default:
516 idle = true;
517 break;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000518 }
Björn Stenbergc40ac322002-06-24 11:02:18 +0000519 if (!idle)
520 row++;
521 break;
522
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000523 case SYS_USB_CONNECTED:
524 usb_screen();
525 return true;
526
Björn Stenbergc40ac322002-06-24 11:02:18 +0000527 default:
528 idle = true;
Björn Stenberg7826fc32002-06-20 10:49:15 +0000529 break;
Eric Linenberg36923362002-06-19 14:26:41 +0000530 }
Björn Stenbergc40ac322002-06-24 11:02:18 +0000531
532 if (!idle) {
533 moves++;
534 lcd_clear_display();
535 update_screen();
536 }
537
Robert Hakd58ab782002-06-16 23:24:22 +0000538 if (boxes_to_go==0) {
539 moves=0;
540 current_level++;
541 if (current_level == NUM_LEVELS) {
Eric Linenberged693902003-01-16 14:50:34 +0000542 lcd_clear_display();
543 lcd_putsxy(10, 20, str(LANG_SOKOBAN_WIN));
544 for(ii=0; ii<30000 ; ii++) {
Eric Linenberg36923362002-06-19 14:26:41 +0000545 lcd_invertrect(0,0,111,63);
Eric Linenbergea0d06f2002-06-19 14:29:01 +0000546 lcd_update();
Björn Stenberg7826fc32002-06-20 10:49:15 +0000547 if ( button_get(false) )
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000548 return false;
Robert Hakd58ab782002-06-16 23:24:22 +0000549 }
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000550 return false;
Robert Hakd58ab782002-06-16 23:24:22 +0000551 }
552 load_level(current_level);
553 lcd_clear_display();
554 update_screen();
Eric Linenberged693902003-01-16 14:50:34 +0000555 copy_current_state_to_undo();
556 copy_current_undo_to_state();
Robert Hakd58ab782002-06-16 23:24:22 +0000557 }
558 }
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000559
560 return false;
Robert Hakd58ab782002-06-16 23:24:22 +0000561}
562
563
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000564bool sokoban(void)
Robert Hakd58ab782002-06-16 23:24:22 +0000565{
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000566 bool result;
Robert Hakd58ab782002-06-16 23:24:22 +0000567 int w, h;
Björn Stenberga4c3b032002-09-24 18:04:15 +0000568 int len;
Robert Hakd58ab782002-06-16 23:24:22 +0000569
Robert Hak8f11dc02002-10-29 10:45:29 +0000570 lcd_setfont(FONT_SYSFIXED);
571
Björn Stenberga4c3b032002-09-24 18:04:15 +0000572 lcd_getstringsize(SOKOBAN_TITLE, &w, &h);
Robert Hakd58ab782002-06-16 23:24:22 +0000573
574 /* Get horizontel centering for text */
Björn Stenberga4c3b032002-09-24 18:04:15 +0000575 len = w;
Robert Hakd58ab782002-06-16 23:24:22 +0000576 if (len%2 != 0)
577 len = ((len+1)/2)+(w/2);
578 else
579 len /= 2;
580
581 if (h%2 != 0)
582 h = (h/2)+1;
583 else
584 h /= 2;
585
586 lcd_clear_display();
Björn Stenberga4c3b032002-09-24 18:04:15 +0000587 lcd_putsxy(LCD_WIDTH/2-len, (LCD_HEIGHT/2)-h, SOKOBAN_TITLE);
Eric Linenberg36923362002-06-19 14:26:41 +0000588
589 lcd_update();
590 sleep(HZ*2);
591
592 lcd_clear_display();
593
Robert Hak03e521f2003-02-21 18:58:34 +0000594 lcd_putsxy(3, 6, str(LANG_SOKOBAN_QUIT));
595 lcd_putsxy(3, 16, str(LANG_SOKOBAN_ON));
596 lcd_putsxy(3, 26, str(LANG_SOKOBAN_F1));
597 lcd_putsxy(3, 36, str(LANG_SOKOBAN_F2));
598 lcd_putsxy(3, 46, str(LANG_SOKOBAN_F3));
Robert Hakd58ab782002-06-16 23:24:22 +0000599
600 lcd_update();
601 sleep(HZ*2);
602 lcd_clear_display();
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000603 result = sokoban_loop();
Daniel Stenbergb2850762002-08-23 12:32:52 +0000604
Robert Hak8f11dc02002-10-29 10:45:29 +0000605 lcd_setfont(FONT_UI);
606
Björn Stenbergb1b8bd42002-09-24 17:22:12 +0000607 return result;
Robert Hakd58ab782002-06-16 23:24:22 +0000608}
Robert Hake0248c52002-08-31 22:55:40 +0000609
610#endif