blob: 21dcebbdb04f51412e574e0a8b24257738814b10 [file] [log] [blame]
Björn Stenberg973d7a92003-07-02 21:38:08 +00001/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Itai Shaked
11 *
Daniel Stenberg2acc0ac2008-06-28 18:10:04 +000012 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
Björn Stenberg973d7a92003-07-02 21:38:08 +000016 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21
22/*
23Snake!
24
25by Itai Shaked
26
27ok, a little explanation -
28board holds the snake and apple position - 1+ - snake body (the number
29represents the age [1 is the snake's head]).
30-1 is an apple, and 0 is a clear spot.
31dir is the current direction of the snake - 0=up, 1=right, 2=down, 3=left;
32
33*/
34
35#include "plugin.h"
36#ifdef HAVE_LCD_BITMAP
37
Jens Arnolda36b1d42006-01-15 18:20:18 +000038PLUGIN_HEADER
39
Jens Arnolde35a6582004-10-18 21:45:00 +000040/* variable button definitions */
41#if CONFIG_KEYPAD == RECORDER_PAD
42#define SNAKE_QUIT BUTTON_OFF
Jens Arnold29361ab2008-03-22 10:24:28 +000043#define SNAKE_LEFT BUTTON_LEFT
44#define SNAKE_RIGHT BUTTON_RIGHT
Dave Chapman54d44c82005-12-14 01:31:37 +000045#define SNAKE_UP BUTTON_UP
46#define SNAKE_DOWN BUTTON_DOWN
Jens Arnolde35a6582004-10-18 21:45:00 +000047#define SNAKE_PLAYPAUSE BUTTON_PLAY
48
Dave Chapmand64e6262007-01-14 13:48:09 +000049#elif CONFIG_KEYPAD == ARCHOS_AV300_PAD
50#define SNAKE_QUIT BUTTON_OFF
Jens Arnold29361ab2008-03-22 10:24:28 +000051#define SNAKE_LEFT BUTTON_LEFT
52#define SNAKE_RIGHT BUTTON_RIGHT
Dave Chapmand64e6262007-01-14 13:48:09 +000053#define SNAKE_UP BUTTON_UP
54#define SNAKE_DOWN BUTTON_DOWN
55#define SNAKE_PLAYPAUSE BUTTON_SELECT
56
Jens Arnolde35a6582004-10-18 21:45:00 +000057#elif CONFIG_KEYPAD == ONDIO_PAD
58#define SNAKE_QUIT BUTTON_OFF
Jens Arnold29361ab2008-03-22 10:24:28 +000059#define SNAKE_LEFT BUTTON_LEFT
60#define SNAKE_RIGHT BUTTON_RIGHT
Dave Chapman54d44c82005-12-14 01:31:37 +000061#define SNAKE_UP BUTTON_UP
62#define SNAKE_DOWN BUTTON_DOWN
Jens Arnolde35a6582004-10-18 21:45:00 +000063#define SNAKE_PLAYPAUSE BUTTON_MENU
64
Daniel Stenberg01377e22005-06-29 12:47:24 +000065#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
66 (CONFIG_KEYPAD == IRIVER_H300_PAD)
Daniel Stenberg6700ad82005-02-04 12:41:09 +000067#define SNAKE_QUIT BUTTON_OFF
Jens Arnold29361ab2008-03-22 10:24:28 +000068#define SNAKE_LEFT BUTTON_LEFT
69#define SNAKE_RIGHT BUTTON_RIGHT
Dave Chapman54d44c82005-12-14 01:31:37 +000070#define SNAKE_UP BUTTON_UP
71#define SNAKE_DOWN BUTTON_DOWN
Daniel Stenberg6700ad82005-02-04 12:41:09 +000072#define SNAKE_PLAYPAUSE BUTTON_ON
73
Kevin Ferrare0e027bd2006-06-30 16:43:47 +000074#define SNAKE_RC_QUIT BUTTON_RC_STOP
75
Dave Chapmanfb4e3842006-02-24 20:54:09 +000076#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
Jens Arnoldb7013222007-07-27 09:57:27 +000077 (CONFIG_KEYPAD == IPOD_3G_PAD) || \
78 (CONFIG_KEYPAD == IPOD_1G2G_PAD)
Dave Chapman54d44c82005-12-14 01:31:37 +000079#define SNAKE_QUIT (BUTTON_SELECT|BUTTON_MENU)
Jens Arnold29361ab2008-03-22 10:24:28 +000080#define SNAKE_LEFT BUTTON_LEFT
81#define SNAKE_RIGHT BUTTON_RIGHT
Dave Chapman54d44c82005-12-14 01:31:37 +000082#define SNAKE_UP BUTTON_MENU
83#define SNAKE_DOWN BUTTON_PLAY
84#define SNAKE_PLAYPAUSE BUTTON_SELECT
85
Jens Arnold85a226d2007-03-16 23:02:39 +000086#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
Daniel Stenbergcedba882006-01-18 11:09:06 +000087#define SNAKE_QUIT BUTTON_POWER
Jens Arnold29361ab2008-03-22 10:24:28 +000088#define SNAKE_LEFT BUTTON_LEFT
89#define SNAKE_RIGHT BUTTON_RIGHT
Daniel Stenbergcedba882006-01-18 11:09:06 +000090#define SNAKE_UP BUTTON_UP
91#define SNAKE_DOWN BUTTON_DOWN
92#define SNAKE_PLAYPAUSE BUTTON_PLAY
93
Marcoen Hirschberg338e2bb2006-02-24 15:42:52 +000094#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
Marcoen Hirschberga7168fe2007-05-19 23:38:09 +000095#define SNAKE_QUIT BUTTON_POWER
Jens Arnold29361ab2008-03-22 10:24:28 +000096#define SNAKE_LEFT BUTTON_LEFT
97#define SNAKE_RIGHT BUTTON_RIGHT
Marcoen Hirschberg338e2bb2006-02-24 15:42:52 +000098#define SNAKE_UP BUTTON_UP
99#define SNAKE_DOWN BUTTON_DOWN
100#define SNAKE_PLAYPAUSE BUTTON_SELECT
101
Marianne Arnold12ddb8e2007-09-20 10:49:48 +0000102#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
103(CONFIG_KEYPAD == SANSA_C200_PAD)
Barry Wardell24f4a2a2006-10-26 13:38:09 +0000104#define SNAKE_QUIT BUTTON_POWER
Jens Arnold29361ab2008-03-22 10:24:28 +0000105#define SNAKE_LEFT BUTTON_LEFT
106#define SNAKE_RIGHT BUTTON_RIGHT
Barry Wardell24f4a2a2006-10-26 13:38:09 +0000107#define SNAKE_UP BUTTON_UP
108#define SNAKE_DOWN BUTTON_DOWN
109#define SNAKE_PLAYPAUSE BUTTON_SELECT
110
Daniel Stenberg1e88be52006-08-03 20:17:25 +0000111#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
112#define SNAKE_QUIT BUTTON_POWER
Jens Arnold29361ab2008-03-22 10:24:28 +0000113#define SNAKE_LEFT BUTTON_LEFT
114#define SNAKE_RIGHT BUTTON_RIGHT
Daniel Stenberg1e88be52006-08-03 20:17:25 +0000115#define SNAKE_UP BUTTON_SCROLL_UP
116#define SNAKE_DOWN BUTTON_SCROLL_DOWN
117#define SNAKE_PLAYPAUSE BUTTON_PLAY
118
Will Robertson8215b342008-02-17 12:23:02 +0000119#elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
120#define SNAKE_QUIT BUTTON_BACK
Jens Arnold29361ab2008-03-22 10:24:28 +0000121#define SNAKE_LEFT BUTTON_LEFT
122#define SNAKE_RIGHT BUTTON_RIGHT
Will Robertson8215b342008-02-17 12:23:02 +0000123#define SNAKE_UP BUTTON_UP
124#define SNAKE_DOWN BUTTON_DOWN
125#define SNAKE_PLAYPAUSE BUTTON_SELECT
126
Robert Kuklad6c8b572008-03-01 22:55:09 +0000127#elif (CONFIG_KEYPAD == MROBE100_PAD)
128#define SNAKE_QUIT BUTTON_POWER
Jens Arnold29361ab2008-03-22 10:24:28 +0000129#define SNAKE_LEFT BUTTON_LEFT
130#define SNAKE_RIGHT BUTTON_RIGHT
Robert Kuklad6c8b572008-03-01 22:55:09 +0000131#define SNAKE_UP BUTTON_UP
132#define SNAKE_DOWN BUTTON_DOWN
133#define SNAKE_PLAYPAUSE BUTTON_SELECT
134
Jens Arnold29361ab2008-03-22 10:24:28 +0000135#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
136#define SNAKE_QUIT BUTTON_RC_REC
137#define SNAKE_LEFT BUTTON_RC_REW
138#define SNAKE_RIGHT BUTTON_RC_FF
139#define SNAKE_UP BUTTON_RC_VOL_UP
140#define SNAKE_DOWN BUTTON_RC_VOL_DOWN
141#define SNAKE_PLAYPAUSE BUTTON_RC_PLAY
142
143#define SNAKE_RC_QUIT BUTTON_REC
144
Rob Purchase554d7ed2008-03-22 22:03:34 +0000145#elif (CONFIG_KEYPAD == COWOND2_PAD)
146#define SNAKE_QUIT BUTTON_POWER
Rob Purchase554d7ed2008-03-22 22:03:34 +0000147
Daniel Stenberg6700ad82005-02-04 12:41:09 +0000148#else
Robert Kuklad6c8b572008-03-01 22:55:09 +0000149#error No keymap defined!
Jens Arnolde35a6582004-10-18 21:45:00 +0000150#endif
151
Rob Purchase297e0502008-04-27 15:30:19 +0000152#ifdef HAVE_TOUCHPAD
153#ifndef SNAKE_QUIT
154#define SNAKE_QUIT BUTTON_TOPLEFT
155#endif
156#ifndef SNAKE_LEFT
157#define SNAKE_LEFT BUTTON_MIDLEFT
158#endif
159#ifndef SNAKE_RIGHT
160#define SNAKE_RIGHT BUTTON_MIDRIGHT
161#endif
162#ifndef SNAKE_UP
163#define SNAKE_UP BUTTON_TOPMIDDLE
164#endif
165#ifndef SNAKE_DOWN
166#define SNAKE_DOWN BUTTON_BOTTOMMIDDLE
167#endif
168#ifndef SNAKE_PLAYPAUSE
169#define SNAKE_PLAYPAUSE BUTTON_CENTER
170#endif
171#endif
172
Michiel Van Der Kolk40efb122005-06-05 15:30:27 +0000173#define BOARD_WIDTH (LCD_WIDTH/4)
174#define BOARD_HEIGHT (LCD_HEIGHT/4)
175
176static int board[BOARD_WIDTH][BOARD_HEIGHT],snakelength;
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000177static unsigned int score,hiscore=0,level=1;
178static short dir,frames,apple,dead=0;
Steve Bavin65265772008-05-13 09:57:56 +0000179static const struct plugin_api* rb;
Björn Stenberg973d7a92003-07-02 21:38:08 +0000180
181void die (void)
182{
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000183 char pscore[17];
Björn Stenberg973d7a92003-07-02 21:38:08 +0000184 rb->lcd_clear_display();
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000185 rb->snprintf(pscore,sizeof(pscore),"Your score: %d",score);
186 rb->lcd_puts(0,0,"Oops...");
187 rb->lcd_puts(0,1, pscore);
Björn Stenberg973d7a92003-07-02 21:38:08 +0000188 if (score>hiscore) {
189 hiscore=score;
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000190 rb->lcd_puts(0,2,"New High Score!");
Björn Stenberg973d7a92003-07-02 21:38:08 +0000191 }
192 else {
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000193 rb->snprintf(pscore,sizeof(pscore),"High Score: %d",hiscore);
194 rb->lcd_puts(0,2,pscore);
Björn Stenberg973d7a92003-07-02 21:38:08 +0000195 }
196 rb->lcd_update();
197 rb->sleep(3*HZ);
198 dead=1;
199}
200
201void colission (short x, short y)
202{
203 switch (board[x][y]) {
204 case 0:
205 break;
206 case -1:
207 snakelength+=2;
208 score+=level;
209 apple=0;
210 break;
211 default:
212 die();
213 break;
214 }
Michiel Van Der Kolk40efb122005-06-05 15:30:27 +0000215 if (x==BOARD_WIDTH || x<0 || y==BOARD_HEIGHT || y<0)
Björn Stenberg973d7a92003-07-02 21:38:08 +0000216 die();
217}
218
219void move_head (short x, short y)
220{
221 switch (dir) {
222 case 0:
223 y-=1;
224 break;
225 case 1:
226 x+=1;
227 break;
228 case 2:
229 y+=1;
230 break;
231 case 3:
232 x-=1;
233 break;
234 }
235 colission (x,y);
236 if (dead)
237 return;
238 board[x][y]=1;
239 rb->lcd_fillrect(x*4,y*4,4,4);
240}
241
242void frame (void)
243{
244 short x,y,head=0;
Michiel Van Der Kolk40efb122005-06-05 15:30:27 +0000245 for (x=0; x<BOARD_WIDTH; x++) {
246 for (y=0; y<BOARD_HEIGHT; y++) {
Björn Stenberg973d7a92003-07-02 21:38:08 +0000247 switch (board[x][y]) {
248 case 1:
249 if (!head) {
250 move_head(x,y);
251 if (dead)
252 return;
253 board[x][y]++;
254 head=1;
255 }
256 break;
257 case 0:
258 break;
259 case -1:
260 break;
261 default:
262 if (board[x][y]==snakelength) {
263 board[x][y]=0;
Jens Arnold04daef12005-06-24 22:33:21 +0000264 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
265 rb->lcd_fillrect(x*4,y*4,4,4);
266 rb->lcd_set_drawmode(DRMODE_SOLID);
Björn Stenberg973d7a92003-07-02 21:38:08 +0000267 }
268 else
269 board[x][y]++;
270 break;
271 }
272 }
273 }
274 rb->lcd_update();
275}
276
277void redraw (void)
278{
279 short x,y;
280 rb->lcd_clear_display();
Michiel Van Der Kolk40efb122005-06-05 15:30:27 +0000281 for (x=0; x<BOARD_WIDTH; x++) {
282 for (y=0; y<BOARD_HEIGHT; y++) {
Björn Stenberg973d7a92003-07-02 21:38:08 +0000283 switch (board[x][y]) {
284 case -1:
285 rb->lcd_fillrect((x*4)+1,y*4,2,4);
286 rb->lcd_fillrect(x*4,(y*4)+1,4,2);
287 break;
288 case 0:
289 break;
290 default:
291 rb->lcd_fillrect(x*4,y*4,4,4);
292 break;
293 }
294 }
295 }
296 rb->lcd_update();
297}
298
299void game_pause (void) {
Jens Arnolde35a6582004-10-18 21:45:00 +0000300 int button;
Björn Stenberg973d7a92003-07-02 21:38:08 +0000301 rb->lcd_clear_display();
302 rb->lcd_putsxy(3,12,"Game Paused");
Jens Arnolde35a6582004-10-18 21:45:00 +0000303#if CONFIG_KEYPAD == RECORDER_PAD
Björn Stenberg973d7a92003-07-02 21:38:08 +0000304 rb->lcd_putsxy(3,22,"[Play] to resume");
Jens Arnolde35a6582004-10-18 21:45:00 +0000305#elif CONFIG_KEYPAD == ONDIO_PAD
Jens Arnoldb8c9a0c2004-12-26 14:56:05 +0000306 rb->lcd_putsxy(3,22,"[Mode] to resume");
Jens Arnolde35a6582004-10-18 21:45:00 +0000307#endif
Björn Stenberg973d7a92003-07-02 21:38:08 +0000308 rb->lcd_putsxy(3,32,"[Off] to quit");
309 rb->lcd_update();
310 while (1) {
Jens Arnolde35a6582004-10-18 21:45:00 +0000311 button=rb->button_get(true);
312 switch (button) {
Kevin Ferrare0e027bd2006-06-30 16:43:47 +0000313#ifdef SNAKE_RC_QUIT
314 case SNAKE_RC_QUIT:
315#endif
Jens Arnolde35a6582004-10-18 21:45:00 +0000316 case SNAKE_QUIT:
Björn Stenberg973d7a92003-07-02 21:38:08 +0000317 dead=1;
318 return;
Jens Arnolde35a6582004-10-18 21:45:00 +0000319 case SNAKE_PLAYPAUSE:
Björn Stenberg973d7a92003-07-02 21:38:08 +0000320 redraw();
321 rb->sleep(HZ/2);
322 return;
Jens Arnolde35a6582004-10-18 21:45:00 +0000323 default:
324 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
325 dead=2;
326 return;
327 }
328 break;
Björn Stenberg973d7a92003-07-02 21:38:08 +0000329 }
330 }
331}
332
333
334void game (void) {
Jens Arnolde35a6582004-10-18 21:45:00 +0000335 int button;
Björn Stenberg973d7a92003-07-02 21:38:08 +0000336 short x,y;
337 while (1) {
338 frame();
339 if (dead)
340 return;
341 frames++;
342 if (frames==10) {
343 frames=0;
344 if (!apple) {
345 do {
Michiel Van Der Kolk40efb122005-06-05 15:30:27 +0000346 x=rb->rand() % BOARD_WIDTH;
347 y=rb->rand() % BOARD_HEIGHT;
Björn Stenberg973d7a92003-07-02 21:38:08 +0000348 } while (board[x][y]);
349 apple=1;
350 board[x][y]=-1;
351 rb->lcd_fillrect((x*4)+1,y*4,2,4);
352 rb->lcd_fillrect(x*4,(y*4)+1,4,2);
353 }
354 }
355
356 rb->sleep(HZ/level);
357
Jens Arnolde35a6582004-10-18 21:45:00 +0000358 button=rb->button_get(false);
Shachar Liberman5360df92006-07-30 03:10:09 +0000359
360#ifdef HAS_BUTTON_HOLD
361 if (rb->button_hold())
362 button = SNAKE_PLAYPAUSE;
363#endif
364
Jens Arnolde35a6582004-10-18 21:45:00 +0000365 switch (button) {
Dave Chapman54d44c82005-12-14 01:31:37 +0000366 case SNAKE_UP:
Björn Stenberg973d7a92003-07-02 21:38:08 +0000367 if (dir!=2) dir=0;
368 break;
Jens Arnold29361ab2008-03-22 10:24:28 +0000369 case SNAKE_RIGHT:
Björn Stenberg973d7a92003-07-02 21:38:08 +0000370 if (dir!=3) dir=1;
371 break;
Dave Chapman54d44c82005-12-14 01:31:37 +0000372 case SNAKE_DOWN:
Björn Stenberg973d7a92003-07-02 21:38:08 +0000373 if (dir!=0) dir=2;
374 break;
Jens Arnold29361ab2008-03-22 10:24:28 +0000375 case SNAKE_LEFT:
Björn Stenberg973d7a92003-07-02 21:38:08 +0000376 if (dir!=1) dir=3;
377 break;
Kevin Ferrare0e027bd2006-06-30 16:43:47 +0000378#ifdef SNAKE_RC_QUIT
379 case SNAKE_RC_QUIT:
380#endif
Jens Arnolde35a6582004-10-18 21:45:00 +0000381 case SNAKE_QUIT:
Björn Stenberg973d7a92003-07-02 21:38:08 +0000382 dead=1;
383 return;
Jens Arnolde35a6582004-10-18 21:45:00 +0000384 case SNAKE_PLAYPAUSE:
Björn Stenberg973d7a92003-07-02 21:38:08 +0000385 game_pause();
386 break;
Jens Arnolde35a6582004-10-18 21:45:00 +0000387 default:
388 if (rb->default_event_handler(button)==SYS_USB_CONNECTED) {
389 dead=2;
390 return;
391 }
392 break;
393 }
Björn Stenberg973d7a92003-07-02 21:38:08 +0000394 }
395}
396
397void game_init(void) {
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000398 int selection=0;
Björn Stenberg973d7a92003-07-02 21:38:08 +0000399 short x,y;
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000400 bool menu_quit = false;
Björn Stenberg973d7a92003-07-02 21:38:08 +0000401
Michiel Van Der Kolk40efb122005-06-05 15:30:27 +0000402 for (x=0; x<BOARD_WIDTH; x++) {
403 for (y=0; y<BOARD_HEIGHT; y++) {
Björn Stenberg973d7a92003-07-02 21:38:08 +0000404 board[x][y]=0;
405 }
406 }
407 dead=0;
408 apple=0;
409 snakelength=4;
410 score=0;
411 board[11][7]=1;
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000412
413 MENUITEM_STRINGLIST(menu,"Snake Menu",NULL,"Start New Game","Starting Level",
414 "Quit");
415
416 while (!menu_quit) {
Jonathan Gordon5ca15392008-03-26 03:35:24 +0000417 switch(rb->do_menu(&menu, &selection, NULL, false))
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000418 {
419 case 0:
420 menu_quit = true; /* start playing */
Björn Stenberg973d7a92003-07-02 21:38:08 +0000421 break;
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000422
423 case 1:
424 rb->set_int("Starting Level", "", UNIT_INT, &level, NULL,
425 1, 1, 9, NULL );
Björn Stenberg973d7a92003-07-02 21:38:08 +0000426 break;
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000427
Jens Arnolde35a6582004-10-18 21:45:00 +0000428 default:
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000429 dead=1; /* quit program */
430 menu_quit = true;
Jens Arnolde35a6582004-10-18 21:45:00 +0000431 break;
Tom Rossc7f5ccc2007-03-28 07:33:18 +0000432
Björn Stenberg973d7a92003-07-02 21:38:08 +0000433 }
Björn Stenberg973d7a92003-07-02 21:38:08 +0000434 }
Björn Stenberg973d7a92003-07-02 21:38:08 +0000435}
436
Steve Bavin65265772008-05-13 09:57:56 +0000437enum plugin_status plugin_start(const struct plugin_api* api, const void* parameter)
Björn Stenberg973d7a92003-07-02 21:38:08 +0000438{
Björn Stenberg973d7a92003-07-02 21:38:08 +0000439 (void)(parameter);
440 rb = api;
441
442 game_init();
443 rb->lcd_clear_display();
Jens Arnolde35a6582004-10-18 21:45:00 +0000444 game();
445 return (dead==1)?PLUGIN_OK:PLUGIN_USB_CONNECTED;
Björn Stenberg973d7a92003-07-02 21:38:08 +0000446}
447
448#endif