summaryrefslogtreecommitdiff
path: root/apps/plugins
diff options
context:
space:
mode:
authorAntoine Cellerier <dionoea@videolan.org>2006-08-02 22:17:21 +0000
committerAntoine Cellerier <dionoea@videolan.org>2006-08-02 22:17:21 +0000
commit5e2a9a19cf97129580b5567527824ce89078d3fd (patch)
treeddef6df574bb6d3d4878eca97a4930d6fb6c03b1 /apps/plugins
parentc00c94e1a4f2099aadc2569c1300125396ad5203 (diff)
downloadrockbox-5e2a9a19cf97129580b5567527824ce89078d3fd.zip
rockbox-5e2a9a19cf97129580b5567527824ce89078d3fd.tar.gz
rockbox-5e2a9a19cf97129580b5567527824ce89078d3fd.tar.bz2
rockbox-5e2a9a19cf97129580b5567527824ce89078d3fd.tar.xz
Cleanup solitaire code a bit. A side effect is that it should now be possible to play on small LCD screens like the recorder's (which had become impossible since revision 1.20).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10422 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins')
-rw-r--r--apps/plugins/solitaire.c1615
1 files changed, 815 insertions, 800 deletions
diff --git a/apps/plugins/solitaire.c b/apps/plugins/solitaire.c
index a9a0d5c..e85872e 100644
--- a/apps/plugins/solitaire.c
+++ b/apps/plugins/solitaire.c
@@ -7,7 +7,7 @@
* \/ \/ \/ \/ \/
* $Id$
*
- * Copyright (C) 2004-2006 dionoea (Antoine Cellerier)
+ * Copyright (C) 2004-2006 Antoine Cellerier <dionoea @t videolan d.t org>
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
@@ -36,253 +36,246 @@ use F3 to put card on top of the remains' stack on one of the 4 final stacks
#include "button.h"
#include "lcd.h"
-
#ifdef HAVE_LCD_BITMAP
PLUGIN_HEADER
-/* here is a global api struct pointer. while not strictly necessary,
- it's nice not to have to pass the api pointer in all function calls
- in the plugin */
static struct plugin_api* rb;
-
#define min(a,b) (a<b?a:b)
+/**
+ * Key definitions
+ */
-/* variable button definitions */
-#if CONFIG_KEYPAD == RECORDER_PAD
-#define SOL_QUIT BUTTON_OFF
-#define SOL_UP BUTTON_UP
-#define SOL_DOWN BUTTON_DOWN
-#define SOL_LEFT BUTTON_LEFT
-#define SOL_RIGHT BUTTON_RIGHT
-#define SOL_MOVE BUTTON_ON
-#define SOL_DRAW BUTTON_F2
-#define SOL_REM2CUR BUTTON_PLAY
-#define SOL_CUR2STACK BUTTON_F1
-#define SOL_REM2STACK BUTTON_F3
-#define SOL_MENU_RUN BUTTON_RIGHT
-#define SOL_MENU_RUN2 BUTTON_PLAY
-#define SOL_MENU_INFO BUTTON_F1
-#define SOL_MENU_INFO2 BUTTON_F2
-#define SOL_MENU_INFO3 BUTTON_F3
-
-#elif CONFIG_KEYPAD == ONDIO_PAD
-#define SOL_QUIT BUTTON_OFF
-#define SOL_UP_PRE BUTTON_UP
-#define SOL_UP (BUTTON_UP | BUTTON_REL)
-#define SOL_DOWN_PRE BUTTON_DOWN
-#define SOL_DOWN (BUTTON_DOWN | BUTTON_REL)
-#define SOL_LEFT_PRE BUTTON_LEFT
-#define SOL_LEFT (BUTTON_LEFT | BUTTON_REL)
-#define SOL_RIGHT_PRE BUTTON_RIGHT
-#define SOL_RIGHT (BUTTON_RIGHT | BUTTON_REL)
-#define SOL_MOVE_PRE BUTTON_MENU
-#define SOL_MOVE (BUTTON_MENU | BUTTON_REL)
-#define SOL_DRAW_PRE BUTTON_MENU
-#define SOL_DRAW (BUTTON_MENU | BUTTON_REPEAT)
-#define SOL_REM2CUR_PRE BUTTON_LEFT
-#define SOL_REM2CUR (BUTTON_LEFT | BUTTON_REPEAT)
-#define SOL_CUR2STACK_PRE BUTTON_RIGHT
-#define SOL_CUR2STACK (BUTTON_RIGHT | BUTTON_REPEAT)
-#define SOL_REM2STACK_PRE BUTTON_UP
-#define SOL_REM2STACK (BUTTON_UP | BUTTON_REPEAT)
-#define SOL_MENU_RUN BUTTON_RIGHT
-#define SOL_MENU_INFO BUTTON_MENU
-
-#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
- (CONFIG_KEYPAD == IRIVER_H300_PAD)
-#define SOL_QUIT BUTTON_OFF
-#define SOL_UP BUTTON_UP
-#define SOL_DOWN BUTTON_DOWN
-#define SOL_LEFT BUTTON_LEFT
-#define SOL_RIGHT BUTTON_RIGHT
-#define SOL_MOVE_PRE BUTTON_SELECT
-#define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
-#define SOL_DRAW BUTTON_MODE
-#define SOL_REM2CUR (BUTTON_LEFT | BUTTON_ON)
-#define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
-#define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_ON)
-#define SOL_MENU_RUN BUTTON_SELECT
-#define SOL_MENU_RUN2 BUTTON_RIGHT
-#define SOL_MENU_INFO BUTTON_MODE
-#define SOL_OPT BUTTON_ON
-#define SOL_REM BUTTON_REC
-
-#define SOL_RC_QUIT BUTTON_RC_STOP
-
-#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
- (CONFIG_KEYPAD == IPOD_3G_PAD)
-#define SOL_QUIT (BUTTON_SELECT | BUTTON_MENU)
-#define SOL_UP BUTTON_MENU
-#define SOL_DOWN BUTTON_PLAY
-#define SOL_LEFT BUTTON_LEFT
-#define SOL_RIGHT BUTTON_RIGHT
-#define SOL_MOVE BUTTON_SELECT
-#define SOL_DRAW (BUTTON_SELECT | BUTTON_PLAY)
-#define SOL_REM2CUR (BUTTON_SELECT | BUTTON_LEFT)
-#define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_RIGHT)
-#define SOL_REM2STACK (BUTTON_LEFT | BUTTON_RIGHT)
-#define SOL_MENU_RUN BUTTON_SELECT
-#define SOL_MENU_INFO (BUTTON_PLAY | BUTTON_MENU)
-
-#elif (CONFIG_KEYPAD == IAUDIO_X5_PAD)
-#define SOL_QUIT BUTTON_POWER
-#define SOL_UP BUTTON_UP
-#define SOL_DOWN BUTTON_DOWN
-#define SOL_LEFT BUTTON_LEFT
-#define SOL_RIGHT BUTTON_RIGHT
-#define SOL_MOVE BUTTON_SELECT
-#define SOL_DRAW BUTTON_PLAY
-#define SOL_REM2CUR (BUTTON_REC | BUTTON_LEFT)
-#define SOL_CUR2STACK (BUTTON_REC | BUTTON_UP)
-#define SOL_REM2STACK (BUTTON_REC | BUTTON_DOWN)
-#define SOL_MENU_RUN BUTTON_SELECT
-#define SOL_MENU_INFO BUTTON_PLAY
-
-#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
-#define SOL_QUIT BUTTON_A
-#define SOL_UP BUTTON_UP
-#define SOL_DOWN BUTTON_DOWN
-#define SOL_LEFT BUTTON_LEFT
-#define SOL_RIGHT BUTTON_RIGHT
-#define SOL_MOVE_PRE BUTTON_SELECT
-#define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
-#define SOL_DRAW BUTTON_MENU
-#define SOL_REM2CUR (BUTTON_LEFT | BUTTON_POWER)
-#define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
-#define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_POWER)
-#define SOL_MENU_RUN BUTTON_SELECT
-#define SOL_MENU_RUN2 BUTTON_RIGHT
-#define SOL_MENU_INFO BUTTON_MENU
-#endif
-
-/* common help definitions */
-#define HELP_SOL_UP "UP: Move the cursor up in the column."
-#define HELP_SOL_DOWN "DOWN: Move the cursor down in the column."
-#define HELP_SOL_LEFT "LEFT: Move the cursor to the previous column."
-#define HELP_SOL_RIGHT "RIGHT: Move the cursor to the next column."
-
-/* variable help definitions */
#if CONFIG_KEYPAD == RECORDER_PAD
-#define HELP_SOL_MOVE "ON: Select cards, Move cards, reveal hidden cards ..."
-#define HELP_SOL_DRAW "F2: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack."
-#define HELP_SOL_REM2CUR "PLAY: Put the card on top of the remains' stack on top of the cursor."
-#define HELP_SOL_CUR2STACK "F1: Put the card under the cursor on one of the 4 final stacks."
-#define HELP_SOL_REM2STACK "F3: Put the card on top of the remains' stack on one of the 4 final stacks."
+# define SOL_QUIT BUTTON_OFF
+# define SOL_UP BUTTON_UP
+# define SOL_DOWN BUTTON_DOWN
+# define SOL_LEFT BUTTON_LEFT
+# define SOL_RIGHT BUTTON_RIGHT
+# define SOL_MOVE BUTTON_ON
+# define SOL_DRAW BUTTON_F2
+# define SOL_REM2CUR BUTTON_PLAY
+# define SOL_CUR2STACK BUTTON_F1
+# define SOL_REM2STACK BUTTON_F3
+# define SOL_MENU_RUN BUTTON_RIGHT
+# define SOL_MENU_RUN2 BUTTON_PLAY
+# define HK_MOVE "ON"
+# define HK_DRAW "F2"
+# define HK_REM2CUR "PLAY"
+# define HK_CUR2STACK "F1"
+# define HK_REM2STACK "F3"
#elif CONFIG_KEYPAD == ONDIO_PAD
-#define HELP_SOL_MOVE "MODE: Select cards, Move cards, reveal hidden cards ..."
-#define HELP_SOL_DRAW "MODE..: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack."
-#define HELP_SOL_REM2CUR "LEFT..: Put the card on top of the remains' stack on top of the cursor."
-#define HELP_SOL_CUR2STACK "RIGHT..: Put the card under the cursor on one of the 4 final stacks."
-#define HELP_SOL_REM2STACK "UP..: Put the card on top of the remains' stack on one of the 4 final stacks."
+# define SOL_QUIT BUTTON_OFF
+# define SOL_UP_PRE BUTTON_UP
+# define SOL_UP (BUTTON_UP | BUTTON_REL)
+# define SOL_DOWN_PRE BUTTON_DOWN
+# define SOL_DOWN (BUTTON_DOWN | BUTTON_REL)
+# define SOL_LEFT_PRE BUTTON_LEFT
+# define SOL_LEFT (BUTTON_LEFT | BUTTON_REL)
+# define SOL_RIGHT_PRE BUTTON_RIGHT
+# define SOL_RIGHT (BUTTON_RIGHT | BUTTON_REL)
+# define SOL_MOVE_PRE BUTTON_MENU
+# define SOL_MOVE (BUTTON_MENU | BUTTON_REL)
+# define SOL_DRAW_PRE BUTTON_MENU
+# define SOL_DRAW (BUTTON_MENU | BUTTON_REPEAT)
+# define SOL_REM2CUR_PRE BUTTON_LEFT
+# define SOL_REM2CUR (BUTTON_LEFT | BUTTON_REPEAT)
+# define SOL_CUR2STACK_PRE BUTTON_RIGHT
+# define SOL_CUR2STACK (BUTTON_RIGHT | BUTTON_REPEAT)
+# define SOL_REM2STACK_PRE BUTTON_UP
+# define SOL_REM2STACK (BUTTON_UP | BUTTON_REPEAT)
+# define SOL_MENU_RUN BUTTON_RIGHT
+# define HK_MOVE "MODE"
+# define HK_DRAW "MODE.."
+# define HK_REM2CUR "LEFT.."
+# define HK_CUR2STACK "RIGHT.."
+# define HK_REM2STACK "UP.."
#elif (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
(CONFIG_KEYPAD == IRIVER_H300_PAD)
-#define HELP_SOL_MOVE "SELECT: Select cards, Move cards, reveal hidden cards ..."
-#define HELP_SOL_DRAW "REC: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack."
-#define HELP_SOL_REM2CUR "PLAY+LEFT: Put the card on top of the remains' stack on top of the cursor."
-#define HELP_SOL_CUR2STACK "SELECT..: Put the card under the cursor on one of the 4 final stacks."
-#define HELP_SOL_REM2STACK "PLAY+RIGHT: Put the card on top of the remains' stack on one of the 4 final stacks."
+# define SOL_QUIT BUTTON_OFF
+# define SOL_UP BUTTON_UP
+# define SOL_DOWN BUTTON_DOWN
+# define SOL_LEFT BUTTON_LEFT
+# define SOL_RIGHT BUTTON_RIGHT
+# define SOL_MOVE_PRE BUTTON_SELECT
+# define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
+# define SOL_DRAW BUTTON_MODE
+# define SOL_REM2CUR (BUTTON_LEFT | BUTTON_ON)
+# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
+# define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_ON)
+# define SOL_MENU_RUN BUTTON_SELECT
+# define SOL_MENU_RUN2 BUTTON_RIGHT
+# define SOL_OPT BUTTON_ON
+# define SOL_REM BUTTON_REC
+# define SOL_RC_QUIT BUTTON_RC_STOP
+# define HK_MOVE "SELECT"
+# define HK_DRAW "REC"
+# define HK_REM2CUR "PLAY+LEFT"
+# define HK_CUR2STACK "SELECT"
+# define HK_REM2STACK "PLAY+RIGHT"
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) ||(CONFIG_KEYPAD == IPOD_3G_PAD)
-#define HELP_SOL_MOVE "SELECT: Select cards, Move cards, reveal hidden cards ..."
-#define HELP_SOL_DRAW "SELECT+PLAY: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack."
-#define HELP_SOL_REM2CUR "SELECT+LEFT: Put the card on top of the remains' stack on top of the cursor."
-#define HELP_SOL_CUR2STACK "SELECT+RIGHT..: Put the card under the cursor on one of the 4 final stacks."
-#define HELP_SOL_REM2STACK "LEFT+RIGHT: Put the card on top of the remains' stack on one of the 4 final stacks."
+# define SOL_QUIT (BUTTON_SELECT | BUTTON_MENU)
+# define SOL_UP BUTTON_MENU
+# define SOL_DOWN BUTTON_PLAY
+# define SOL_LEFT BUTTON_LEFT
+# define SOL_RIGHT BUTTON_RIGHT
+# define SOL_MOVE BUTTON_SELECT
+# define SOL_DRAW (BUTTON_SELECT | BUTTON_PLAY)
+# define SOL_REM2CUR (BUTTON_SELECT | BUTTON_LEFT)
+# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_RIGHT)
+# define SOL_REM2STACK (BUTTON_LEFT | BUTTON_RIGHT)
+# define SOL_MENU_RUN BUTTON_SELECT
+# define HK_MOVE "SELECT"
+# define HK_DRAW "SELECT+PLAY"
+# define HK_REM2CUR "SELECT+LEFT"
+# define HK_CUR2STACK "SELECT+RIGHT.."
+# define HK_REM2STACK "LEFT+RIGHT"
#elif (CONFIG_KEYPAD == IAUDIO_X5_PAD)
-#define HELP_SOL_MOVE "MENU: Select cards, Move cards, reveal hidden cards ..."
-#define HELP_SOL_DRAW "PLAY: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack."
-#define HELP_SOL_REM2CUR "REC+LEFT: Put the card on top of the remains' stack on top of the cursor."
-#define HELP_SOL_CUR2STACK "REC+UP..: Put the card under the cursor on one of the 4 final stacks."
-#define HELP_SOL_REM2STACK "REC+DOWN: Put the card on top of the remains' stack on one of the 4 final stacks."
+# define SOL_QUIT BUTTON_POWER
+# define SOL_UP BUTTON_UP
+# define SOL_DOWN BUTTON_DOWN
+# define SOL_LEFT BUTTON_LEFT
+# define SOL_RIGHT BUTTON_RIGHT
+# define SOL_MOVE BUTTON_SELECT
+# define SOL_DRAW BUTTON_PLAY
+# define SOL_REM2CUR (BUTTON_REC | BUTTON_LEFT)
+# define SOL_CUR2STACK (BUTTON_REC | BUTTON_UP)
+# define SOL_REM2STACK (BUTTON_REC | BUTTON_DOWN)
+# define SOL_MENU_RUN BUTTON_SELECT
+# define HK_MOVE "MENU"
+# define HK_DRAW "PLAY"
+# define HK_REM2CUR "REC+LEFT"
+# define HK_CUR2STACK "REC+UP.."
+# define HK_REM2STACK "REC+DOWN"
#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
-#define HELP_SOL_MOVE "SELECT: Select cards, Move cards, reveal hidden cards ..."
-#define HELP_SOL_DRAW "MENU: Un-select a card if it was selected. Else, draw 3 new cards out of the remains' stack."
-#define HELP_SOL_REM2CUR "POWER+LEFT: Put the card on top of the remains' stack on top of the cursor."
-#define HELP_SOL_CUR2STACK "SELECT..: Put the card under the cursor on one of the 4 final stacks."
-#define HELP_SOL_REM2STACK "POWER+RIGHT: Put the card on top of the remains' stack on one of the 4 final stacks."
+# define SOL_QUIT BUTTON_A
+# define SOL_UP BUTTON_UP
+# define SOL_DOWN BUTTON_DOWN
+# define SOL_LEFT BUTTON_LEFT
+# define SOL_RIGHT BUTTON_RIGHT
+# define SOL_MOVE_PRE BUTTON_SELECT
+# define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
+# define SOL_DRAW BUTTON_MENU
+# define SOL_REM2CUR (BUTTON_LEFT | BUTTON_POWER)
+# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
+# define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_POWER)
+# define SOL_MENU_RUN BUTTON_SELECT
+# define SOL_MENU_RUN2 BUTTON_RIGHT
+# define HK_MOVE "SELECT"
+# define HK_DRAW "MENU"
+# define HK_REM2CUR "POWER+LEFT"
+# define HK_CUR2STACK "SELECT.."
+# define HK_REM2STACK "POWER+RIGHT"
-#endif
-
-#if LCD_DEPTH>1
-static const unsigned colors[4] = {
-#ifdef HAVE_LCD_COLOR
- LCD_BLACK, LCD_RGBPACK(255, 0, 0), LCD_BLACK, LCD_RGBPACK(255, 0, 0)
#else
- LCD_BLACK, LCD_BRIGHTNESS(127), LCD_BLACK, LCD_BRIGHTNESS(127)
-#endif
-};
+# error "Unknown keypad"
#endif
-#define BMPHEIGHT_c 10
-#define BMPWIDTH_c 8
+/**
+ * Help strings
+ */
+
+#define HELP_SOL_UP "UP: Move the cursor up in the column."
+#define HELP_SOL_DOWN "DOWN: Move the cursor down in the column."
+#define HELP_SOL_LEFT "LEFT: Move the cursor to the previous column."
+#define HELP_SOL_RIGHT "RIGHT: Move the cursor to the next column."
+#define HELP_SOL_MOVE HK_MOVE \
+ ": Select cards, Move cards, reveal hidden cards ..."
+#define HELP_SOL_DRAW HK_DRAW \
+ ": Un-select a card if it was selected. " \
+ "Else, draw 3 new cards out of the remains' stack."
+#define HELP_SOL_REM2CUR HK_REM2CUR \
+ ": Put the card on top of the remains' stack on top of the cursor."
+#define HELP_SOL_CUR2STACK HK_CUR2STACK \
+ ": Put the card under the cursor on one of the 4 final stacks."
+#define HELP_SOL_REM2STACK HK_REM2STACK \
+ ": Put the card on top of the remains' stack on one of the 4 final stacks."
+
+/**
+ * Misc constants, graphics and other defines
+ */
-#ifdef HAVE_LCD_COLOR
+/* size of a card on the screen */
#if (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
-#define BMPHEIGHT_CARDBACK 33
-#define BMPWIDTH_CARDBACK 26
+# define CARD_WIDTH 27
+# define CARD_HEIGHT 34
+#elif LCD_HEIGHT > 64
+# define CARD_WIDTH 19
+# define CARD_HEIGHT 24
#else
-#define BMPHEIGHT_CARDBACK 24
-#define BMPWIDTH_CARDBACK 18
+# define CARD_WIDTH 14
+# define CARD_HEIGHT 10
#endif
-extern const fb_data solitaire_cardback[];
+/* where the cards start */
+#define CARD_START ( CARD_HEIGHT + 4 )
+
+#if LCD_HEIGHT > 64
+# define NUMBER_HEIGHT 10
+# define NUMBER_WIDTH 8
+# define NUMBER_STRIDE 8
+# define SUIT_HEIGHT 10
+# define SUIT_WIDTH 8
+# define SUIT_STRIDE 8
+#else
+# define NUMBER_HEIGHT 6
+# define NUMBER_WIDTH 6
+# define NUMBER_STRIDE 6
+# define SUIT_HEIGHT 6
+# define SUIT_WIDTH 6
+# define SUIT_STRIDE 6
#endif
-static const unsigned char suitsi[4][30] = {
- {0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xfc, 0xf8, 0xf0, 0xe0, 0xc0, 0x80, 0x00, 0x00, 0x07, 0x0f, 0x1f, 0x1f, 0x0f, 0x7f, 0x7f, 0x7f, 0x0f, 0x1f, 0x1f, 0x0f, 0x07, 0x00},
- {0x00, 0xf0, 0xf8, 0xfc, 0xfe, 0xfc, 0xf8, 0xf0, 0xf8, 0xfc, 0xfe, 0xfc, 0xf8, 0xf0, 0x00, 0x00, 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01, 0x00, 0x00},
- {0x00, 0xc0, 0xe0, 0xe0, 0xfc, 0xfe, 0xfe, 0xfe, 0xfe, 0xfe, 0xfc, 0xe0, 0xe0, 0xc0, 0x00, 0x00, 0x03, 0x07, 0x07, 0x0f, 0x0f, 0x7f, 0x7f, 0x7f, 0x0f, 0x0f, 0x07, 0x07, 0x03, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x80, 0xe0, 0xf8, 0xfe, 0xfe, 0xf8, 0xe0, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x07, 0x1f, 0x7f, 0x7f, 0x1f, 0x07, 0x01, 0x00, 0x00, 0x00},
-};
-static const unsigned char suits[4][16] = {
-/* Spades */
- {0x00, 0x78, 0x3c, 0xfe, 0xfe, 0x3c, 0x78, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00},/* ........ */
-/* Hearts */
- {0x00, 0x3c, 0x7e, 0xfc, 0xf8, 0xfc, 0x7e, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00},/* ........ */
-/* Clubs */
- {0x00, 0x70, 0x34, 0xfe, 0xfe, 0x34, 0x70, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00},/* ........ */
-/* Diamonds */
- {0x00, 0x70, 0xfc, 0xfe, 0xfe, 0xfc, 0x70, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00} /* ........ */
-};
-
-static unsigned char numbers[13][16] = {
-/* Ace */
- {0x00, 0xf0, 0xfc, 0x7e, 0x36, 0x7e, 0xfc, 0xf0, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01},
-/* 2 */
- {0x00, 0x8c, 0xce, 0xe6, 0xf6, 0xbe, 0x9c, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* ........ */
-/* 3 */
- {0x00, 0xcc, 0x86, 0xb6, 0xb6, 0xfe, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /* ........ */
-/* 4 */
- {0x00, 0x3e, 0x3e, 0x30, 0xfe, 0xfe, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00}, /* ........ */
-/* 5 */
- {0x00, 0xbe, 0xbe, 0xb6, 0xb6, 0xf6, 0xe6, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /* ........ */
-/* 6 */
- {0x00, 0xfc, 0xfe, 0xb6, 0xb6, 0xf6, 0xe4, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /* ........ */
-/* 7 */
- {0x00, 0x86, 0xc6, 0x66, 0x36, 0x1e, 0x0e, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00}, /* ........ */
-/* 8 */
- {0x00, 0xdc, 0xfe, 0xb6, 0xb6, 0xfe, 0xdc, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /* ........ */
-/* 9 */
- {0x00, 0x9c, 0xbe, 0xb6, 0xb6, 0xfe, 0xfc, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00}, /* ........ */
-/* 10 */
- {0x00, 0x18, 0x0c, 0xfe, 0x00, 0xfc, 0x86, 0xfc, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00}, /* ........ */
-/* Jack */
- {0x00, 0xe6, 0xc6, 0x86, 0xfe, 0xfe, 0x06, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00}, /* ........ */
-/* Queen */
- {0x00, 0x7c, 0xfe, 0xc6, 0xe6, 0xfe, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* ........ */
-/* King */
- {0x00, 0xfe, 0xfe, 0x38, 0x7c, 0xee, 0xc6, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00} /* ........ */
-};
-
+#define SUITI_HEIGHT 16
+#define SUITI_WIDTH 15
+#define SUITI_STRIDE 16
+
+
+#define draw_number( num, x, y ) \
+ rb->lcd_bitmap_part( numbers, 0, num * NUMBER_HEIGHT, NUMBER_STRIDE, \
+ x, y, NUMBER_WIDTH, NUMBER_HEIGHT );
+extern const fb_data solitaire_numbers[];
+#define numbers solitaire_numbers
+
+#define draw_suit( num, x, y ) \
+ rb->lcd_bitmap_part( suits, 0, num * SUIT_HEIGHT, SUIT_STRIDE, \
+ x, y, SUIT_WIDTH, SUIT_HEIGHT );
+extern const fb_data solitaire_suits[];
+#define suits solitaire_suits
+
+#if ( CARD_HEIGHT < SUITI_HEIGHT + 1 ) || ( CARD_WIDTH < SUITI_WIDTH + 1 )
+# undef SUITI_HEIGHT
+# undef SUITI_WIDTH
+# define SUITI_HEIGHT SUIT_HEIGHT
+# define SUITI_WIDTH SUIT_WIDTH
+# define draw_suiti( num, x, y ) draw_suit( num, x, y )
+#else
+# define draw_suiti( num, x, y ) \
+ rb->lcd_bitmap_part( suitsi, 0, num * SUITI_HEIGHT, SUITI_STRIDE, \
+ x, y, SUITI_WIDTH, SUITI_HEIGHT );
+ extern const fb_data solitaire_suitsi[];
+# define suitsi solitaire_suitsi
+#endif
-#define FILENAME "sol.cfg"
+#ifdef HAVE_LCD_COLOR
+# if (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
+# define CARDBACK_HEIGHT 33
+# define CARDBACK_WIDTH 26
+# else
+# define CARDBACK_HEIGHT 24
+# define CARDBACK_WIDTH 18
+# endif
+
+ extern const fb_data solitaire_cardback[];
+#endif
+#define CONFIG_FILENAME "sol.cfg"
#define NOT_A_CARD 255
@@ -292,76 +285,155 @@ static unsigned char numbers[13][16] = {
/* number of suits */
#define SUITS 4
+#define NUM_CARDS ( CARDS_PER_SUIT * SUITS )
+
/* number of columns */
#define COL_NUM 7
/* pseudo column numbers to be used for cursor coordinates */
-/* columns COL_NUM t COL_NUM + SUITS - 1 correspond to the final stacks */
+/* columns COL_NUM to COL_NUM + SUITS - 1 correspond to the final stacks */
#define STACKS_COL COL_NUM
/* column COL_NUM + SUITS corresponds to the remains' stack */
#define REM_COL (STACKS_COL + SUITS)
#define NOT_A_COL 255
+/* background color */
+#define BACKGROUND_COLOR LCD_RGBPACK(0,157,0)
-/* size of a card on the screen */
-#if (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
-#define CARD_WIDTH 26
-#define CARD_HEIGHT 34
-#else
-#define CARD_WIDTH 18
-#define CARD_HEIGHT 24
-#endif
-
-/* where the cards start */
-#define CARD_START CARD_HEIGHT +4
-
-#if (LCD_WIDTH >= 220) && (LCD_HEIGHT >= 176)
-#define KNOWN_CARD 23
-#define NOT_KNOWN_CARD 30
-#else
-#define KNOWN_CARD 13
-#define NOT_KNOWN_CARD 20
+#if LCD_DEPTH > 1 && !defined( LCD_WHITE )
+# define LCD_WHITE LCD_DEFAULT_BG
#endif
-/* background color */
-#define background_color LCD_RGBPACK(0,157,0)
-
-typedef struct card {
+typedef struct
+{
unsigned char suit : 2;
unsigned char num : 4;
unsigned char known : 1;
unsigned char used : 1;/* this is what is used when dealing cards */
unsigned char next;
-} card;
+} card_t;
-unsigned char next_random_card(card *deck){
- unsigned char i,r;
- r = rb->rand()%(SUITS * CARDS_PER_SUIT)+1;
- i = 0;
+/**
+ * LCD card drawing routines
+ */
+
+static void draw_cursor( int x, int y )
+{
+ rb->lcd_set_drawmode( DRMODE_COMPLEMENT );
+ rb->lcd_fillrect( x+1, y+1, CARD_WIDTH-1, CARD_HEIGHT-1 );
+ rb->lcd_set_drawmode( DRMODE_SOLID );
+}
- while(r>0){
- i = (i + 1)%(SUITS * CARDS_PER_SUIT);
- if(!deck[i].used) r--;
+/* Draw a card's border, select it if it's selected and draw the cursor
+ * is the cursor is currently over the card */
+static void draw_card_ext( int x, int y, bool selected, bool cursor )
+{
+#if LCD_DEPTH > 1
+ rb->lcd_set_foreground( LCD_BLACK );
+#endif
+ /* draw a rectangle omiting the corner pixels, which is why we don't
+ * use drawrect */
+ rb->lcd_drawline( x+1, y, x+CARD_WIDTH-1, y );
+ rb->lcd_drawline( x+1, y+CARD_HEIGHT, x+CARD_WIDTH-1, y+CARD_HEIGHT );
+ rb->lcd_drawline( x, y+1, x, y+CARD_HEIGHT-1 );
+ rb->lcd_drawline( x+CARD_WIDTH, y+1, x+CARD_WIDTH, y+CARD_HEIGHT-1 );
+
+ if( selected )
+ {
+ rb->lcd_drawrect( x+1, y+1, CARD_WIDTH-1, CARD_HEIGHT-1 );
}
+ if( cursor )
+ {
+ draw_cursor( x, y );
+ }
+}
- deck[i].used = 1;
+/* Draw a card's inner graphics */
+static void draw_card( card_t card, int x, int y,
+ bool selected, bool cursor, bool leftstyle )
+{
+#ifndef HAVE_LCD_COLOR
+ /* On Black&White or Greyscale LCDs we don't have a card back.
+ * We thus need to clear the card area even if the card isn't
+ * known. */
+#if LCD_DEPTH > 1
+ rb->lcd_set_foreground( LCD_WHITE );
+#else
+ rb->lcd_set_drawmode( DRMODE_SOLID|DRMODE_INVERSEVID );
+#endif
+ rb->lcd_fillrect( x+1, y+1, CARD_WIDTH-1, CARD_HEIGHT-1 );
+#if LCD_DEPTH == 1
+ rb->lcd_set_drawmode( DRMODE_SOLID );
+#endif
+#endif
+ if( card.known )
+ {
+#ifdef HAVE_LCD_COLOR
+ /* On Color LCDs we have a card back so we only need to clear
+ * the card area when it's known*/
+ rb->lcd_set_foreground( LCD_WHITE );
+ rb->lcd_fillrect( x+1, y+1, CARD_WIDTH-1, CARD_HEIGHT-1 );
+#endif
+ draw_number( card.num, x+1, y+1 );
+ if( leftstyle )
+ {
+ draw_suit( card.suit, x+1, y+2+NUMBER_HEIGHT );
+ }
+ else
+ {
+ draw_suit( card.suit, x+2+NUMBER_WIDTH, y+1 );
+ }
+ }
+#ifdef HAVE_LCD_COLOR
+ else
+ {
+ rb->lcd_bitmap( solitaire_cardback, x+1, y+1,
+ CARDBACK_WIDTH, CARDBACK_HEIGHT );
+ }
+#endif
- return i;
+ draw_card_ext( x, y, selected, cursor );
+}
+
+/* Draw an empty stack */
+static void draw_empty_stack( int s, int x, int y, bool cursor )
+{
+#if LCD_DEPTH > 1
+ rb->lcd_set_foreground( LCD_WHITE );
+#else
+ rb->lcd_set_drawmode( DRMODE_SOLID|DRMODE_INVERSEVID );
+#endif
+ rb->lcd_fillrect( x+1, y+1, CARD_WIDTH-1, CARD_HEIGHT-1 );
+#if LCD_DEPTH == 1
+ rb->lcd_set_drawmode( DRMODE_SOLID );
+#endif
+ draw_suiti( s, x+(CARD_WIDTH-SUITI_WIDTH)/2,
+ y+(CARD_HEIGHT-SUITI_HEIGHT)/2 );
+
+ draw_card_ext( x, y, false, cursor );
}
-#define HELP_QUIT 0
-#define HELP_USB 1
+/**
+ * Help
+ *
+ * TODO: the help menu should just list the key definitions. Asking the
+ * user to try all possible keys/key combos is just counter
+ * productive.
+ */
+
+enum help { HELP_QUIT, HELP_USB };
/* help for the not so intuitive interface */
-int solitaire_help(void){
+enum help solitaire_help( void )
+{
int button;
int lastbutton = BUTTON_NONE;
- while(1){
-
+ while( true )
+ {
rb->lcd_clear_display();
#if CONFIG_KEYPAD == RECORDER_PAD
@@ -388,82 +460,85 @@ int solitaire_help(void){
rb->lcd_putsxy(20, 48, "All actions can be");
rb->lcd_putsxy(20, 56, "done using the");
rb->lcd_putsxy(20, 64, "joystick and RECORD.");
+#else
+//# warning "Add help strings for other keypads"
#endif
rb->lcd_update();
- button = rb->button_get(true);
- switch(button){
+ button = rb->button_get( true );
+ switch( button )
+ {
case SOL_UP:
#ifdef SOL_UP_PRE
- if(lastbutton != SOL_UP_PRE)
+ if( lastbutton != SOL_UP_PRE )
break;
#endif
- rb->splash(HZ*2, true, HELP_SOL_UP);
+ rb->splash( HZ*2, true, HELP_SOL_UP );
break;
case SOL_DOWN:
#ifdef SOL_DOWN_PRE
- if(lastbutton != SOL_DOWN_PRE)
+ if( lastbutton != SOL_DOWN_PRE )
break;
#endif
- rb->splash(HZ*2, true, HELP_SOL_DOWN);
+ rb->splash( HZ*2, true, HELP_SOL_DOWN );
break;
case SOL_LEFT:
#ifdef SOL_LEFT_PRE
- if(lastbutton != SOL_LEFT_PRE)
+ if( lastbutton != SOL_LEFT_PRE )
break;
#endif
- rb->splash(HZ*2, true, HELP_SOL_LEFT);
+ rb->splash( HZ*2, true, HELP_SOL_LEFT );
break;
case SOL_RIGHT:
#ifdef SOL_RIGHT_PRE
- if(lastbutton != SOL_RIGHT_PRE)
+ if( lastbutton != SOL_RIGHT_PRE )
break;
#endif
- rb->splash(HZ*2, true, HELP_SOL_RIGHT);
+ rb->splash( HZ*2, true, HELP_SOL_RIGHT );
break;
case SOL_MOVE:
#ifdef SOL_MOVE_PRE
- if(lastbutton != SOL_MOVE_PRE)
+ if( lastbutton != SOL_MOVE_PRE )
break;
#endif
- rb->splash(HZ*2, true, HELP_SOL_MOVE);
+ rb->splash( HZ*2, true, HELP_SOL_MOVE );
break;
case SOL_DRAW:
#ifdef SOL_DRAW_PRE
- if(lastbutton != SOL_DRAW_PRE)
+ if( lastbutton != SOL_DRAW_PRE )
break;
#endif
- rb->splash(HZ*2, true, HELP_SOL_DRAW);
+ rb->splash( HZ*2, true, HELP_SOL_DRAW );
break;
case SOL_CUR2STACK:
#ifdef SOL_CUR2STACK_PRE
- if(lastbutton != SOL_CUR2STACK_PRE)
+ if( lastbutton != SOL_CUR2STACK_PRE )
break;
#endif
- rb->splash(HZ*2, true, HELP_SOL_CUR2STACK);
+ rb->splash( HZ*2, true, HELP_SOL_CUR2STACK );
break;
case SOL_REM2STACK:
#ifdef SOL_REM2STACK_PRE
- if(lastbutton != SOL_REM2STACK_PRE)
+ if( lastbutton != SOL_REM2STACK_PRE )
break;
#endif
- rb->splash(HZ*2, true, HELP_SOL_REM2STACK);
+ rb->splash( HZ*2, true, HELP_SOL_REM2STACK );
break;
case SOL_REM2CUR:
#ifdef SOL_REM2CUR_PRE
- if(lastbutton != SOL_REM2CUR_PRE)
+ if( lastbutton != SOL_REM2CUR_PRE )
break;
#endif
- rb->splash(HZ*2, true, HELP_SOL_REM2CUR);
+ rb->splash( HZ*2, true, HELP_SOL_REM2CUR );
break;
#ifdef SOL_RC_QUIT
case SOL_RC_QUIT:
@@ -472,48 +547,40 @@ int solitaire_help(void){
return HELP_QUIT;
default:
- if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
+ if( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
return HELP_USB;
break;
}
- if(button != BUTTON_NONE)
+ if( button != BUTTON_NONE )
lastbutton = button;
}
}
+
+/**
+ * Custom menu / options
+ *
+ * TODO: use rockbox api menus instead
+ */
+
#define CFGFILE_VERSION 0
int draw_type;
-
-unsigned char change_draw(unsigned char draw){
- if (draw == 0)
- return 1;
- else
- return 0;
-}
static struct configdata config[] = {
{ TYPE_INT, 0, 1, &draw_type, "draw_type", NULL, NULL }
};
/* menu return codes */
-#define MENU_RESUME 0
-#define MENU_RESTART 1
-#define MENU_HELP 3
-#define MENU_QUIT 4
-#define MENU_USB 5
-#define MENU_OPT 2
-
-/* menu item number */
-#define MENU_LENGTH 5
+enum { MENU_RESUME, MENU_RESTART, MENU_OPT,
+ MENU_HELP, MENU_QUIT, MENU_USB };
+#define MENU_LENGTH MENU_USB
/* different menu behaviors */
+enum { MENU_BEFOREGAME, MENU_BEFOREGAMEOP, MENU_DURINGGAME };
-#define MENU_BEFOREGAME 0
-#define MENU_BEFOREGAMEOP 1
-#define MENU_DURINGGAME 2
-unsigned char when;
-/* the menu */
-/* text displayed changes depending on the 'when' parameter */
-int solitaire_menu(unsigned char when_n)
+/**
+ * The menu
+ * text displayed changes depending on the context */
+int solitaire_menu( unsigned char context )
{
static char menu[3][MENU_LENGTH][17] =
{ { "Start Game",
@@ -535,34 +602,42 @@ int solitaire_menu(unsigned char when_n)
int i;
- int cursor=0;
+ int cursor = 0;
int button;
+
int fh;
- when=when_n;
- rb->lcd_getstringsize("A", NULL, &fh);
+ rb->lcd_getstringsize( menu[0][0], NULL, &fh );
fh++;
- if(when != MENU_BEFOREGAMEOP && when!=MENU_BEFOREGAME && when!=MENU_DURINGGAME)
- when = MENU_DURINGGAME;
+ if( context != MENU_BEFOREGAMEOP
+ && context != MENU_BEFOREGAME
+ && context != MENU_DURINGGAME )
+ {
+ context = MENU_DURINGGAME;
+ }
- while(1){
+ while( true )
+ {
rb->lcd_clear_display();
- rb->lcd_putsxy(20, 1, "Solitaire");
-
- for(i = 0; i<MENU_LENGTH; i++){
- rb->lcd_putsxy(1, 17+fh*i, menu[when][i]);
- if(cursor == i) {
- rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
- rb->lcd_fillrect(0,17+fh*i, LCD_WIDTH, fh);
- rb->lcd_set_drawmode(DRMODE_SOLID);
+ rb->lcd_putsxy( 20, 1, "Solitaire" );
+
+ for( i = 0; i<MENU_LENGTH; i++ )
+ {
+ rb->lcd_putsxy( 1, 17+fh*i, menu[context][i] );
+ if( cursor == i )
+ {
+ rb->lcd_set_drawmode( DRMODE_COMPLEMENT );
+ rb->lcd_fillrect( 0, 17+fh*i, LCD_WIDTH, fh );
+ rb->lcd_set_drawmode( DRMODE_SOLID );
}
}
rb->lcd_update();
- button = rb->button_get(true);
- switch(button){
+ button = rb->button_get( true );
+ switch( button )
+ {
case SOL_UP:
cursor = (cursor + MENU_LENGTH - 1)%MENU_LENGTH;
break;
@@ -578,7 +653,8 @@ int solitaire_menu(unsigned char when_n)
#ifdef SOL_MENU_RUN2
case SOL_MENU_RUN2:
#endif
- switch(cursor){
+ switch( cursor )
+ {
case MENU_RESUME:
case MENU_RESTART:
case MENU_OPT:
@@ -586,20 +662,12 @@ int solitaire_menu(unsigned char when_n)
return cursor;
case MENU_HELP:
- if(solitaire_help() == HELP_USB)
+ if( solitaire_help() == HELP_USB )
return MENU_USB;
break;
}
break;
- case SOL_MENU_INFO:
-#if defined(SOL_MENU_INFO2) && defined(SOL_MENU_INFO3)
- case SOL_MENU_INFO2:
- case SOL_MENU_INFO3:
-#endif
- rb->splash(HZ, true, "Solitaire for Rockbox by dionoea");
- break;
-
#ifdef SOL_OPT
case SOL_OPT:
return MENU_OPT;
@@ -612,13 +680,17 @@ int solitaire_menu(unsigned char when_n)
return MENU_QUIT;
default:
- if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
+ if( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
return MENU_USB;
break;
}
}
}
+/**
+ * Global variables
+ */
+
/* player's cursor */
unsigned char cur_card;
/* player's cursor column num */
@@ -628,7 +700,7 @@ unsigned char cur_col;
unsigned char sel_card;
/* the deck */
-card deck[SUITS * CARDS_PER_SUIT];
+card_t deck[ NUM_CARDS ];
/* the remaining cards */
unsigned char rem;
@@ -638,51 +710,84 @@ unsigned char coun_rem;
/* the 7 game columns */
unsigned char cols[COL_NUM];
-int CARDS_PER_DRAW;
+int cards_per_draw;
/* the 4 final stacks */
unsigned char stacks[SUITS];
+/**
+ * Card handling routines
+ */
+
+unsigned char next_random_card( card_t *deck )
+{
+ unsigned char i,r;
+
+ r = rb->rand()%(NUM_CARDS)+1;
+ i = 0;
+
+ while( r>0 )
+ {
+ i = (i + 1)%(NUM_CARDS);
+ if( !deck[i].used ) r--;
+ }
+
+ deck[i].used = 1;
+
+ return i;
+}
+
+
/* initialize the game */
-void solitaire_init(void){
+void solitaire_init( void )
+{
unsigned char c;
- int i,j;
-#if LCD_DEPTH>1
- rb->lcd_set_foreground(LCD_BLACK);
-#ifdef HAVE_LCD_COLOR
- rb->lcd_set_background(background_color);
-#endif
-#endif
-/* number of cards that are drawn on the remains' stack (by pressing F2) */
- if(draw_type == 0) {
- CARDS_PER_DRAW =3;
- } else {
- CARDS_PER_DRAW=1;
+ int i, j;
+
+ /* number of cards that are drawn on the remains' stack (by pressing F2) */
+ if( draw_type == 0 )
+ {
+ cards_per_draw = 3;
}
+ else
+ {
+ cards_per_draw = 1;
+ }
+
/* init deck */
- for(i=0;i<SUITS;i++){
- for(j=0;j<CARDS_PER_SUIT;j++){
- deck[i*CARDS_PER_SUIT+j].suit = i;
- deck[i*CARDS_PER_SUIT+j].num = j;
- deck[i*CARDS_PER_SUIT+j].known = 1;
- deck[i*CARDS_PER_SUIT+j].used = 0;
- deck[i*CARDS_PER_SUIT+j].next = NOT_A_CARD;
+ for( i=0; i<SUITS; i++ )
+ {
+ for( j=0; j<CARDS_PER_SUIT; j++ )
+ {
+#define card deck[i*CARDS_PER_SUIT+j]
+ card.suit = i;
+ card.num = j;
+ card.known = 1;
+ card.used = 0;
+ card.next = NOT_A_CARD;
+#undef card
}
}
/* deal the cards ... */
/* ... in the columns */
- for(i=0; i<COL_NUM; i++){
+ for( i=0; i<COL_NUM; i++ )
+ {
c = NOT_A_CARD;
- for(j=0; j<=i; j++){
- if(c == NOT_A_CARD){
- cols[i] = next_random_card(deck);
+ for( j=0; j<=i; j++ )
+ {
+ if( c == NOT_A_CARD )
+ {
+ cols[i] = next_random_card( deck );
c = cols[i];
- } else {
- deck[c].next = next_random_card(deck);
+ }
+ else
+ {
+ deck[c].next = next_random_card( deck );
c = deck[c].next;
}
- if(j<i) deck[c].known = 0;
+ if( j < i )
+ deck[c].known = 0;
}
}
@@ -690,15 +795,17 @@ void solitaire_init(void){
rem = next_random_card(deck);
c = rem;
- for(i=1; i<SUITS * CARDS_PER_SUIT - COL_NUM * (COL_NUM + 1)/2; i++){
- deck[c].next = next_random_card(deck);
+ for( i=1; i < NUM_CARDS - COL_NUM * (COL_NUM + 1)/2; i++ )
+ {
+ deck[c].next = next_random_card( deck );
c = deck[c].next;
}
/* we now finished dealing the cards. The game can start ! (at last) */
/* init the stack */
- for(i = 0; i<SUITS; i++){
+ for( i = 0; i<SUITS; i++ )
+ {
stacks[i] = NOT_A_CARD;
}
@@ -716,24 +823,29 @@ void solitaire_init(void){
}
/* find the column number in which 'card' can be found */
-unsigned char find_card_col(unsigned char card){
+unsigned char find_card_col( unsigned char card )
+{
int i;
unsigned char c;
- if(card == NOT_A_CARD) return NOT_A_COL;
+ if( card == NOT_A_CARD ) return NOT_A_COL;
- for(i=0; i<COL_NUM; i++){
+ for( i=0; i<COL_NUM; i++ )
+ {
c = cols[i];
- while(c!=NOT_A_CARD){
- if(c == card) return i;
+ while( c != NOT_A_CARD )
+ {
+ if( c == card ) return i;
c = deck[c].next;
}
}
- for(i=0; i<SUITS; i++){
+ for( i=0; i<SUITS; i++ )
+ {
c = stacks[i];
- while(c!=NOT_A_CARD){
- if(c == card) return STACKS_COL + i;
+ while( c != NOT_A_CARD )
+ {
+ if( c == card ) return STACKS_COL + i;
c = deck[c].next;
}
}
@@ -743,41 +855,49 @@ unsigned char find_card_col(unsigned char card){
/* find the card preceding 'card' */
/* if it doesn't exist, return NOT_A_CARD */
-unsigned char find_prev_card(unsigned char card){
+unsigned char find_prev_card( unsigned char card ){
int i;
- for(i=0; i<SUITS*CARDS_PER_SUIT; i++){
- if(deck[i].next == card) return i;
+ for( i=0; i < NUM_CARDS; i++ )
+ {
+ if( deck[i].next == card ) return i;
}
return NOT_A_CARD;
}
/* find the last card of a given column */
-unsigned char find_last_card(unsigned char col){
+unsigned char find_last_card( unsigned char col )
+{
unsigned char c;
- if(col < COL_NUM){
+ if( col < COL_NUM )
+ {
c = cols[col];
- } else if(col < REM_COL){
+ }
+ else if( col < REM_COL )
+ {
c = stacks[col - STACKS_COL];
- } else {
+ }
+ else
+ {
c = rem;
}
if(c == NOT_A_CARD)
return c;
- else {
- while(deck[c].next != NOT_A_CARD){
+ else
+ {
+ while(deck[c].next != NOT_A_CARD)
c = deck[c].next;
- }
return c;
}
}
-#define MOVE_OK 0
-#define MOVE_NOT_OK 1
-unsigned char move_card(unsigned char dest_col, unsigned char src_card){
+enum move { MOVE_OK, MOVE_NOT_OK };
+
+enum move move_card( unsigned char dest_col, unsigned char src_card )
+{
/* the column on which to take src_card */
unsigned char src_col;
@@ -788,82 +908,95 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){
unsigned char src_card_prev;
/* you can't move no card (at least, it doesn't have any consequence) */
- if(src_card == NOT_A_CARD) return MOVE_NOT_OK;
+ if( src_card == NOT_A_CARD ) return MOVE_NOT_OK;
/* you can't put a card back on the remains' stack */
- if(dest_col == REM_COL) return MOVE_NOT_OK;
+ if( dest_col == REM_COL ) return MOVE_NOT_OK;
- src_col = find_card_col(src_card);
- dest_card = find_last_card(dest_col);
- src_card_prev = find_prev_card(src_card);
+ src_col = find_card_col( src_card );
+ dest_card = find_last_card( dest_col );
+ src_card_prev = find_prev_card( src_card );
/* you can't move more than one card at a time from the final stack */
/* to the rest of the game */
- if(src_col >= COL_NUM && src_col < REM_COL
- && deck[src_card].next != NOT_A_CARD){
+ if( src_col >= COL_NUM && src_col < REM_COL
+ && deck[src_card].next != NOT_A_CARD )
+ {
return MOVE_NOT_OK;
}
/* if we (that means dest) are on one of the 7 columns ... */
- if(dest_col < COL_NUM){
+ if( dest_col < COL_NUM )
+ {
/* ... check is we are on an empty color and that the src is a king */
- if(dest_card == NOT_A_CARD
- && deck[src_card].num == CARDS_PER_SUIT - 1){
+ if( dest_card == NOT_A_CARD
+ && deck[src_card].num == CARDS_PER_SUIT - 1 )
+ {
/* this is a winning combination */
cols[dest_col] = src_card;
}
/* ... or check if the cards follow one another and have same suit */
- else if((deck[dest_card].suit + deck[src_card].suit)%2==1
- && deck[dest_card].num == deck[src_card].num + 1){
+ else if(( deck[dest_card].suit + deck[src_card].suit)%2==1
+ && deck[dest_card].num == deck[src_card].num + 1 )
+ {
/* this is a winning combination */
deck[dest_card].next = src_card;
}
/* ... or, humpf, well that's not good news */
- else {
+ else
+ {
/* this is not a winning combination */
return MOVE_NOT_OK;
}
}
/* if we are on one of the 4 final stacks ... */
- else if(dest_col < REM_COL){
+ else if( dest_col < REM_COL )
+ {
/* ... check if we are on an empty stack, that the src is an
* ace and that this is the good final stack */
- if(dest_card == NOT_A_CARD
- && deck[src_card].num == 0
- && deck[src_card].suit == dest_col - STACKS_COL){
+ if( dest_card == NOT_A_CARD
+ && deck[src_card].num == 0
+ && deck[src_card].suit == dest_col - STACKS_COL )
+ {
/* this is a winning combination */
stacks[dest_col - STACKS_COL] = src_card;
}
/* ... or check if the cards follow one another, have the same
* suit and {that src has no .next element or is from the remains'
* stack} */
- else if(deck[dest_card].suit == deck[src_card].suit
- && deck[dest_card].num + 1 == deck[src_card].num
- && (deck[src_card].next == NOT_A_CARD || src_col == REM_COL) ){
+ else if( deck[dest_card].suit == deck[src_card].suit
+ && deck[dest_card].num + 1 == deck[src_card].num
+ && (deck[src_card].next == NOT_A_CARD || src_col == REM_COL) )
+ {
/* this is a winning combination */
deck[dest_card].next = src_card;
}
/* ... or, well that's not good news */
- else {
+ else
+ {
/* this is not a winnong combination */
return MOVE_NOT_OK;
}
}
/* if we are on the remains' stack */
- else {
+ else
+ {
/* you can't move a card back to the remains' stack */
return MOVE_NOT_OK;
}
/* if the src card is from the remains' stack, we don't want to take
* the following cards */
- if(src_col == REM_COL){
+ if( src_col == REM_COL )
+ {
/* if src card is the first card from the stack */
- if(src_card_prev == NOT_A_CARD){
+ if( src_card_prev == NOT_A_CARD )
+ {
rem = deck[src_card].next;
coun_rem = coun_rem-1;
}
/* if src card is not the first card from the stack */
- else {
+ else
+ {
deck[src_card_prev].next = deck[src_card].next;
}
deck[src_card].next = NOT_A_CARD;
@@ -871,14 +1004,21 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){
coun_rem = coun_rem-1;
}
/* if the src card is from somewhere else, just take everything */
- else {
- if(src_card_prev == NOT_A_CARD){
- if(src_col < COL_NUM){
+ else
+ {
+ if( src_card_prev == NOT_A_CARD )
+ {
+ if( src_col < COL_NUM )
+ {
cols[src_col] = NOT_A_CARD;
- } else {
+ }
+ else
+ {
stacks[src_col - STACKS_COL] = NOT_A_CARD;
}
- } else {
+ }
+ else
+ {
deck[src_card_prev].next = NOT_A_CARD;
}
}
@@ -887,11 +1027,11 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){
return MOVE_OK;
}
+/**
+ * The main game loop
+ */
-
-#define SOLITAIRE_WIN 0
-#define SOLITAIRE_QUIT 1
-#define SOLITAIRE_USB 2
+enum { SOLITAIRE_WIN, SOLITAIRE_QUIT, SOLITAIRE_USB };
#if ( LCD_WIDTH > ( CARD_WIDTH * 8 ) )
# define BIG_SCREEN 1
@@ -900,416 +1040,254 @@ unsigned char move_card(unsigned char dest_col, unsigned char src_card){
#endif
#define LCD_WIDTH2 (LCD_WIDTH - BIG_SCREEN)
-/* the game */
-int solitaire(void){
+int solitaire( void )
+{
- int i,j,x;
+ int i,j;
int button, lastbutton = 0;
unsigned char c,h,prevcard;
int biggest_col_length;
configfile_init(rb);
- configfile_load(FILENAME, config, 1, 0);
+ configfile_load(CONFIG_FILENAME, config, 1, 0);
rb->srand( *rb->current_tick );
- switch(solitaire_menu(draw_type==0?MENU_BEFOREGAME:MENU_BEFOREGAMEOP)) {
- case MENU_QUIT:
+ switch( solitaire_menu( draw_type == 0 ? MENU_BEFOREGAME
+ : MENU_BEFOREGAMEOP ) )
+ {
+ case MENU_QUIT:
return SOLITAIRE_QUIT;
case MENU_USB:
return SOLITAIRE_USB;
- case MENU_OPT:
- draw_type=change_draw(draw_type);
- configfile_save(FILENAME, config, 1, 0);
- when=draw_type==0?MENU_BEFOREGAME:MENU_BEFOREGAMEOP;
+
+ case MENU_OPT:
+ draw_type = (draw_type+1)%2;
+ configfile_save(CONFIG_FILENAME, config, 1, 0);
return 0;
}
+ solitaire_init();
+
+ while( true )
+ {
+
#if LCD_DEPTH>1
- rb->lcd_set_foreground(LCD_BLACK);
+ rb->lcd_set_foreground(LCD_BLACK);
#ifdef HAVE_LCD_COLOR
- rb->lcd_set_background(background_color);
-#else
- rb->lcd_set_background(LCD_DEFAULT_BG);
+ rb->lcd_set_background(BACKGROUND_COLOR);
#endif
#endif
- solitaire_init();
-
- while(true){
-
rb->lcd_clear_display();
+#if LCD_DEPTH > 1
+ rb->lcd_set_foreground(LCD_BLACK);
+ rb->lcd_set_background(LCD_WHITE);
+#endif
+
/* get the biggest column length so that display can be "optimized" */
biggest_col_length = 0;
- for(i=0;i<COL_NUM;i++){
+ for(i=0;i<COL_NUM;i++)
+ {
j = 0;
c = cols[i];
- while(c != NOT_A_CARD){
+ while( c != NOT_A_CARD )
+ {
j++;
c = deck[c].next;
}
- if(j>biggest_col_length) biggest_col_length = j;
+ if( j > biggest_col_length ) biggest_col_length = j;
}
/* check if there are cards remaining in the game. */
/* if there aren't any, that means you won :) */
- if(biggest_col_length == 0 && rem == NOT_A_CARD){
- rb->splash(HZ*2, true, "You Won :)");
+ if( biggest_col_length == 0 && rem == NOT_A_CARD )
+ {
+ rb->splash( HZ*2, true, "You Won :)" );
return SOLITAIRE_WIN;
}
/* draw the columns */
- for(i=0;i<COL_NUM;i++){
+ for( i = 0; i < COL_NUM; i++ )
+ {
c = cols[i];
j = CARD_START;
- while(true){
- if(c==NOT_A_CARD) {
+ while( true )
+ {
+ if( c == NOT_A_CARD )
+ {
/* draw the cursor on empty columns */
- if(cur_col == i){
- rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
- rb->lcd_fillrect(1+i*(LCD_WIDTH-2)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1);
+ if( cur_col == i )
+ {
+ draw_cursor( 1+i*(LCD_WIDTH - 2)/COL_NUM, j+1 );
}
break;
}
- /* clear the card's spot */
- rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
- rb->lcd_fillrect(1+i*(LCD_WIDTH - 2)/COL_NUM, j+1, CARD_WIDTH, CARD_HEIGHT-1);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- /* known card */
- if(deck[c].known == 1){
-#if LCD_DEPTH>1
- #ifdef HAVE_LCD_COLOR
- rb->lcd_set_foreground(LCD_WHITE);
- rb->lcd_set_background(LCD_WHITE);
- #else
- rb->lcd_set_foreground(LCD_DEFAULT_BG);
- rb->lcd_set_background(LCD_DEFAULT_BG);
- #endif
-#endif
- rb->lcd_fillrect(1+i*(LCD_WIDTH - 2)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1);
-#if LCD_DEPTH>1
- rb->lcd_set_foreground(colors[deck[c].suit]);
-#endif
- rb->lcd_mono_bitmap(numbers[deck[c].num], 1+i*(LCD_WIDTH - 2)/COL_NUM+1, j+1, BMPWIDTH_c, BMPHEIGHT_c);
- rb->lcd_mono_bitmap(suits[deck[c].suit], 1+i*(LCD_WIDTH - 2)/COL_NUM+ BMPWIDTH_c +2, j+1, BMPWIDTH_c, BMPHEIGHT_c);
-#if LCD_DEPTH>1
- rb->lcd_set_foreground(LCD_BLACK);
-#ifdef HAVE_LCD_COLOR
- rb->lcd_set_background(background_color);
-#endif
-#endif
- } else {
-#ifdef HAVE_LCD_COLOR
- rb->lcd_bitmap(solitaire_cardback,
- 1+i*(LCD_WIDTH - 2)/COL_NUM+1, j+1,
- BMPWIDTH_CARDBACK, BMPHEIGHT_CARDBACK);
-#endif
- }
- /* draw top line of the card */
- rb->lcd_drawline(1+i*(LCD_WIDTH - 2)/COL_NUM+1,j,1+i*(LCD_WIDTH - 2)/COL_NUM+CARD_WIDTH-1,j);
- /* selected card */
- if(c == sel_card && sel_card != NOT_A_CARD){
- rb->lcd_drawrect(1+i*(LCD_WIDTH - 2)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1);
- }
- /* cursor (or not) */
- if(c == cur_card){
- rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
- rb->lcd_fillrect(1+i*(LCD_WIDTH - 2)/COL_NUM+1, j+1, CARD_WIDTH-1, CARD_HEIGHT-1);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- /* go to the next card */
- c = deck[c].next;
- if(c == NOT_A_CARD) break;
- else {
- if(deck[c].known == 0) {
- j += CARD_HEIGHT - NOT_KNOWN_CARD;
- } else {
- j += CARD_HEIGHT - KNOWN_CARD;
- }
- }
- } else {
- /* go to the next card */
- h = c;
- c = deck[c].next;
- if(c == NOT_A_CARD) break;
- if(c!=NOT_A_CARD) {
- if(deck[h].known == 0) {
- /*changeeee*/ j += CARD_HEIGHT - NOT_KNOWN_CARD;
- } else {
- j += min(CARD_HEIGHT - KNOWN_CARD, (LCD_HEIGHT - CARD_START - CARD_HEIGHT)/biggest_col_length);
- }
- }
- }
- }
- if(cols[i]!=NOT_A_CARD){
- /* draw line to the left of the column */
- rb->lcd_drawline(1+i*(LCD_WIDTH - 2)/COL_NUM,CARD_START,1+i*(LCD_WIDTH - 2)/COL_NUM,j+CARD_HEIGHT-1);
- /* draw line to the right of the column */
- rb->lcd_drawline(1+i*(LCD_WIDTH - 2)/COL_NUM+CARD_WIDTH,CARD_START,1+i*(LCD_WIDTH - 2)/COL_NUM+CARD_WIDTH,j+CARD_HEIGHT-1);
- /* draw bottom of the last card */
- rb->lcd_drawline(1+i*(LCD_WIDTH - 2)/COL_NUM+1,j+CARD_HEIGHT,1+i*(LCD_WIDTH - 2)/COL_NUM+CARD_WIDTH-1,j+CARD_HEIGHT);
+ draw_card( deck[c], 1+i*(LCD_WIDTH - 2)/COL_NUM, j+1,
+ c == sel_card, c == cur_card, false );
+
+ h = c;
+ c = deck[c].next;
+ if( c == NOT_A_CARD ) break;
+
+ /* This is where we change the spacing between cards so that
+ * they don't overflow out of the LCD */
+ if( h == cur_card )
+ j += SUIT_HEIGHT+2;
+ else
+ j += min( SUIT_HEIGHT+2,
+ (LCD_HEIGHT - CARD_START - CARD_HEIGHT)/biggest_col_length );
}
}
-#if LCD_DEPTH>1
- rb->lcd_set_foreground(LCD_BLACK);
-#ifdef HAVE_LCD_COLOR
- rb->lcd_set_background(background_color);
-#endif
-#endif
- rb->lcd_set_drawmode(DRMODE_SOLID);
- /* draw the stacks */
- for(i=0; i<SUITS; i++){
- c = stacks[i];
- if(c!=NOT_A_CARD){
- while(deck[c].next != NOT_A_CARD){
- c = deck[c].next;
- }
- }
- if(c != NOT_A_CARD) {
-#if LCD_DEPTH>1
- #ifdef HAVE_LCD_COLOR
- rb->lcd_set_foreground(LCD_WHITE);
- rb->lcd_set_background(LCD_WHITE);
- #else
- rb->lcd_set_foreground(LCD_DEFAULT_BG);
- rb->lcd_set_background(LCD_DEFAULT_BG);
- #endif
-#endif
- rb->lcd_fillrect(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, CARD_WIDTH-1, CARD_HEIGHT-1);
-#if LCD_DEPTH>1
- rb->lcd_set_foreground(colors[i]);
-#endif
- rb->lcd_mono_bitmap(numbers[deck[c].num], LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, BMPWIDTH_c, BMPHEIGHT_c);
- rb->lcd_mono_bitmap(suits[deck[c].suit], LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+10, 2, BMPWIDTH_c, BMPHEIGHT_c);
- } else {
-#if LCD_DEPTH>1
- #ifdef HAVE_LCD_COLOR
- rb->lcd_set_foreground(LCD_WHITE);
- rb->lcd_set_background(LCD_WHITE);
- #else
- rb->lcd_set_foreground(LCD_DEFAULT_BG);
- rb->lcd_set_background(LCD_DEFAULT_BG);
- #endif
-#endif
- rb->lcd_fillrect(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, CARD_WIDTH-1, CARD_HEIGHT-1);
-#if LCD_DEPTH>1
- rb->lcd_set_foreground(colors[i]);
-#endif
-#ifdef HAVE_LCD_COLOR
- rb->lcd_mono_bitmap(suitsi[i], LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+(CARD_WIDTH/2-7), CARD_HEIGHT/2-7, 15, 16);
-#endif
- }
-#if LCD_DEPTH>1
- rb->lcd_set_foreground(LCD_BLACK);
-#ifdef HAVE_LCD_COLOR
- rb->lcd_set_background(background_color);
-#endif
-#endif
- /* draw a selected card */
- if(c != NOT_A_CARD) {
- if(sel_card == c){
- rb->lcd_drawrect(LCD_WIDTH2 -(CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, CARD_WIDTH-1, CARD_HEIGHT-1);
- }
+ /* draw the stacks */
+ for( i=0; i<SUITS; i++ )
+ {
+ c = find_last_card( STACKS_COL + i );
+
+ if( c != NOT_A_CARD )
+ {
+ draw_card( deck[c],
+ LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2,
+ c == sel_card, cur_col == STACKS_COL + i, false );
}
- rb->lcd_drawline(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 1,LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+CARD_WIDTH,1);
- rb->lcd_drawline(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2 ,2,LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2,CARD_HEIGHT);
- rb->lcd_drawline(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1,CARD_HEIGHT+1,LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+CARD_WIDTH - 1,CARD_HEIGHT+1);
-#if BIG_SCREEN
- rb->lcd_drawline(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+CARD_WIDTH,2,LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+CARD_WIDTH,CARD_HEIGHT);
-#endif
- /* draw the cursor on one of the stacks */
- if(cur_col == STACKS_COL + i){
- rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
- rb->lcd_fillrect(LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2, CARD_WIDTH-1, CARD_HEIGHT-1);
- rb->lcd_set_drawmode(DRMODE_SOLID);
+ else
+ {
+ draw_empty_stack( i,
+ LCD_WIDTH2 - (CARD_WIDTH*4+8)+CARD_WIDTH*i+i*2+1, 2,
+ cur_col == STACKS_COL + i );
}
}
/* draw the remains */
-
-
- if(rem != NOT_A_CARD) {
- coun_rem = coun_rem>2?coun_rem=2:coun_rem;
- if(cur_rem != NOT_A_CARD && find_prev_card(cur_rem) != NOT_A_CARD && CARDS_PER_DRAW != 1) {
- j = (coun_rem)*(BMPWIDTH_c+2);
- for(i=0;i<=coun_rem;i++) {
- if (i>0 && i<3){
-#if LCD_DEPTH>1
- #ifdef HAVE_LCD_COLOR
- rb->lcd_set_foreground(LCD_WHITE);
- rb->lcd_set_background(LCD_WHITE);
- #else
- rb->lcd_set_foreground(LCD_DEFAULT_BG);
- rb->lcd_set_background(LCD_DEFAULT_BG);
- #endif
-#endif
- rb->lcd_fillrect(CARD_WIDTH+4+j+1, 2, BMPWIDTH_c+1, CARD_HEIGHT-1);
- #if LCD_DEPTH>1
- rb->lcd_set_foreground(LCD_BLACK);
- #endif
- rb->lcd_drawline(CARD_WIDTH+4+j+1,1,CARD_WIDTH+4+j+BMPWIDTH_c+2,1); /* top line */
- rb->lcd_drawline(CARD_WIDTH+4+j+1,CARD_HEIGHT+1,CARD_WIDTH+4+j+BMPWIDTH_c+2,CARD_HEIGHT+1); /* bottom line */
- rb->lcd_drawline(CARD_WIDTH+4+j,2,CARD_WIDTH+4+j,CARD_HEIGHT); /* right line */
-
-
- prevcard = cur_rem;
- for(x=0;i>x;x++)
- prevcard = find_prev_card(prevcard);
- #if LCD_DEPTH>1
- rb->lcd_set_foreground(colors[deck[prevcard].suit]);
- #ifdef HAVE_LCD_COLOR
- rb->lcd_set_background(LCD_WHITE);
- #endif
- #endif
- rb->lcd_mono_bitmap(numbers[deck[prevcard].num], CARD_WIDTH+4+j+1, 3, BMPWIDTH_c, BMPHEIGHT_c);
- rb->lcd_mono_bitmap(suits[deck[prevcard].suit], CARD_WIDTH+4+j+1, 4+BMPHEIGHT_c, BMPWIDTH_c, BMPHEIGHT_c);
-
-
- }
- j -= BMPWIDTH_c+2;
- }
- }
-#if LCD_DEPTH>1
- rb->lcd_set_foreground(LCD_BLACK);
-#endif
- if(CARDS_PER_DRAW==1 || cur_rem==NOT_A_CARD)
- j=0;
- else
- j=(coun_rem)*(BMPWIDTH_c+2);
- if(cur_rem != NOT_A_CARD){
- rb->lcd_drawline(CARD_WIDTH+4+j+1,1,CARD_WIDTH+4+j+CARD_WIDTH-1,1); /* top line */
- rb->lcd_drawline(CARD_WIDTH+4+j,2,CARD_WIDTH+4+j,CARD_HEIGHT); /* left line */
- rb->lcd_drawline(CARD_WIDTH+4+j+1,CARD_HEIGHT+1,CARD_WIDTH+4+j+CARD_WIDTH - 1,CARD_HEIGHT+1); /* bottom line */
- rb->lcd_drawline(CARD_WIDTH+4+j+CARD_WIDTH,2,CARD_WIDTH+4+j+CARD_WIDTH,CARD_HEIGHT); /* right line */
- }
-
- rb->lcd_drawline(2,1,CARD_WIDTH+1,1); /* top line */
- rb->lcd_drawline(1,2,1,CARD_HEIGHT); /* left line */
- rb->lcd_drawline(2,CARD_HEIGHT+1,CARD_WIDTH + 1,CARD_HEIGHT+1); /* bottom line */
- rb->lcd_drawline(CARD_WIDTH+2,2,CARD_WIDTH+2,CARD_HEIGHT); /* right line */
-
- if(cur_rem != NOT_A_CARD){
-#if LCD_DEPTH>1
- #ifdef HAVE_LCD_COLOR
- rb->lcd_set_foreground(LCD_WHITE);
- rb->lcd_set_background(LCD_WHITE);
- #else
- rb->lcd_set_foreground(LCD_DEFAULT_BG);
- rb->lcd_set_background(LCD_DEFAULT_BG);
- #endif
-#endif
- rb->lcd_fillrect(CARD_WIDTH+4+j+1, 2, CARD_WIDTH-1, CARD_HEIGHT-1);
- #if LCD_DEPTH>1
- rb->lcd_set_foreground(colors[deck[cur_rem].suit]);
- #endif
- rb->lcd_mono_bitmap(numbers[deck[cur_rem].num], CARD_WIDTH+4+j+1, 3, BMPWIDTH_c, BMPHEIGHT_c);
- rb->lcd_mono_bitmap(suits[deck[cur_rem].suit], CARD_WIDTH+4+j+10, 3, BMPWIDTH_c, BMPHEIGHT_c);
- /* draw a selected card */
- #if LCD_DEPTH>1
- rb->lcd_set_foreground(LCD_BLACK);
- #ifdef HAVE_LCD_COLOR
- rb->lcd_set_background(background_color);
- #endif
- #endif
- if(sel_card == cur_rem){
- rb->lcd_drawrect(CARD_WIDTH+4+j+1, 2,CARD_WIDTH-1, CARD_HEIGHT-1);
- }
- }
- if(rem != NOT_A_CARD){
-#ifdef HAVE_LCD_COLOR
- rb->lcd_bitmap(solitaire_cardback, 2, 2,
- BMPWIDTH_CARDBACK, BMPHEIGHT_CARDBACK);
-#endif
+ if( rem != NOT_A_CARD )
+ {
+ coun_rem = coun_rem>2 ? coun_rem=2 : coun_rem;
+ if( cur_rem != NOT_A_CARD
+ && find_prev_card(cur_rem) != NOT_A_CARD
+ && cards_per_draw != 1 )
+ {
+ j = 0;
+ prevcard = cur_rem;
+ for( i = 0; i < coun_rem; i++ )
+ prevcard = find_prev_card(prevcard);
+ for( i = 0; i <= coun_rem; i++ )
+ {
+ draw_card( deck[prevcard], CARD_WIDTH+4+j+1, 2,
+ sel_card == prevcard, cur_card == prevcard,
+ i < coun_rem );
+ prevcard = deck[prevcard].next;
+ j += NUMBER_WIDTH+2;
}
}
+ else if( cur_rem == NOT_A_CARD && cur_col == REM_COL )
+ {
+ draw_cursor( CARD_WIDTH+4+1, 2 );
+ }
-
- /* draw the cursor */
- if(cur_col == REM_COL && rem != NOT_A_CARD){
- rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
- rb->lcd_fillrect(CARD_WIDTH+4+j+1, 2,CARD_WIDTH-1, CARD_HEIGHT-1);
- rb->lcd_set_drawmode(DRMODE_SOLID);
- } else if(cur_col == REM_COL && rem == NOT_A_CARD) {
- rb->lcd_set_drawmode(DRMODE_COMPLEMENT);
- rb->lcd_fillrect(CARD_WIDTH+4+1, 2,CARD_WIDTH-1, CARD_HEIGHT-1);
- rb->lcd_set_drawmode(DRMODE_SOLID);
+ if( ( prevcard == NOT_A_CARD && rem != NOT_A_CARD )
+ || deck[prevcard].next != NOT_A_CARD )
+ {
+ /* gruik ! (we want to display a card back) */
+ deck[rem].known = false;
+ draw_card( deck[rem], 2, 2, false, false, false );
+ deck[rem].known = true;
+ }
}
-
rb->lcd_update();
/* what to do when a key is pressed ... */
- button = rb->button_get(true);
- switch(button){
-
- /* move cursor to the last card of the previous column */
- /* or to the previous final stack */
- /* or to the remains stack */
+ button = rb->button_get( true );
+ switch( button )
+ {
+ /* move cursor to the last card of the previous column
+ * or to the previous final stack
+ * or to the remains stack */
case SOL_RIGHT:
#ifdef SOL_RIGHT_PRE
- if(lastbutton != SOL_RIGHT_PRE)
+ if( lastbutton != SOL_RIGHT_PRE )
break;
#endif
- if(cur_col >= COL_NUM){
+ if( cur_col >= COL_NUM )
+ {
cur_col = 0;
- } else if(cur_col == COL_NUM - 1){
+ }
+ else if( cur_col == COL_NUM - 1 )
+ {
cur_col = REM_COL;
- } else {
+ }
+ else
+ {
cur_col = (cur_col+1)%(REM_COL+1);
}
- if(cur_col == REM_COL){
+ if(cur_col == REM_COL)
+ {
cur_card = cur_rem;
break;
}
- cur_card = find_last_card(cur_col);
+ cur_card = find_last_card( cur_col );
break;
- /* move cursor to the last card of the next column */
- /* or to the next final stack */
- /* or to the remains stack */
+ /* move cursor to the last card of the next column
+ * or to the next final stack
+ * or to the remains stack */
case SOL_LEFT:
#ifdef SOL_LEFT_PRE
- if(lastbutton != SOL_LEFT_PRE)
+ if( lastbutton != SOL_LEFT_PRE )
break;
#endif
- if(cur_col == 0){
+ if( cur_col == 0 )
+ {
cur_col = REM_COL;
- } else if(cur_col >= COL_NUM) {
+ }
+ else if( cur_col >= COL_NUM )
+ {
cur_col = COL_NUM - 1;
- } else {
+ }
+ else
+ {
cur_col = (cur_col + REM_COL)%(REM_COL+1);
}
- if(cur_col == REM_COL){
+ if( cur_col == REM_COL )
+ {
cur_card = cur_rem;
break;
}
- cur_card = find_last_card(cur_col);
+ cur_card = find_last_card( cur_col );
break;
/* move cursor to card that's bellow */
case SOL_DOWN:
#ifdef SOL_DOWN_PRE
- if(lastbutton != SOL_DOWN_PRE)
+ if( lastbutton != SOL_DOWN_PRE )
break;
#endif
- if(cur_col >= COL_NUM) {
+ if( cur_col >= COL_NUM )
+ {
cur_col = (cur_col - COL_NUM + 1)%(SUITS + 1) + COL_NUM;
- if(cur_col == REM_COL){
+ if( cur_col == REM_COL )
+ {
cur_card = cur_rem;
}
- else {
- cur_card = find_last_card(cur_col);
+ else
+ {
+ cur_card = find_last_card( cur_col );
}
break;
}
- if(cur_card == NOT_A_CARD) break;
- if(deck[cur_card].next != NOT_A_CARD){
+ if( cur_card == NOT_A_CARD ) break;
+ if( deck[cur_card].next != NOT_A_CARD )
+ {
cur_card = deck[cur_card].next;
- } else {
+ }
+ else
+ {
cur_card = cols[cur_col];
- while(deck[cur_card].known == 0
- && deck[cur_card].next != NOT_A_CARD){
+ while( deck[ cur_card].known == 0
+ && deck[cur_card].next != NOT_A_CARD )
+ {
cur_card = deck[cur_card].next;
}
}
@@ -1318,36 +1296,42 @@ int solitaire(void){
/* move cursor to card that's above */
case SOL_UP:
#ifdef SOL_UP_PRE
- if(lastbutton != SOL_UP_PRE)
+ if( lastbutton != SOL_UP_PRE )
break;
#endif
- if(cur_col >= COL_NUM) {
+ if( cur_col >= COL_NUM )
+ {
cur_col = (cur_col - COL_NUM + SUITS)%(SUITS + 1) + COL_NUM;
- if(cur_col == REM_COL){
+ if( cur_col == REM_COL )
+ {
cur_card = cur_rem;
- } else {
- cur_card = find_last_card(cur_col);
+ }
+ else
+ {
+ cur_card = find_last_card( cur_col );
}
break;
}
- if(cur_card == NOT_A_CARD) break;
- do{
- cur_card = find_prev_card(cur_card);
- if(cur_card == NOT_A_CARD){
- cur_card = find_last_card(cur_col);
+ if( cur_card == NOT_A_CARD ) break;
+ do {
+ cur_card = find_prev_card( cur_card );
+ if( cur_card == NOT_A_CARD )
+ {
+ cur_card = find_last_card( cur_col );
}
- } while (deck[cur_card].next != NOT_A_CARD
- && deck[cur_card].known == 0);
+ } while( deck[cur_card].next != NOT_A_CARD
+ && deck[cur_card].known == 0 );
break;
/* Try to put card under cursor on one of the stacks */
case SOL_CUR2STACK:
#ifdef SOL_CUR2STACK_PRE
- if(lastbutton != SOL_CUR2STACK_PRE)
+ if( lastbutton != SOL_CUR2STACK_PRE )
break;
#endif
- if(cur_card != NOT_A_CARD){
- move_card(deck[cur_card].suit + STACKS_COL, cur_card);
+ if( cur_card != NOT_A_CARD )
+ {
+ move_card( deck[cur_card].suit + STACKS_COL, cur_card );
sel_card = NOT_A_CARD;
}
break;
@@ -1355,116 +1339,141 @@ int solitaire(void){
/* Move cards arround, Uncover cards, ... */
case SOL_MOVE:
#ifdef SOL_MOVE_PRE
- if(lastbutton != SOL_MOVE_PRE)
+ if( lastbutton != SOL_MOVE_PRE )
break;
#endif
- if(sel_card == NOT_A_CARD) {
- if(cur_card != NOT_A_CARD) {
- /* reveal a hidden card */
- if(deck[cur_card].next == NOT_A_CARD && deck[cur_card].known==0){
+ if( sel_card == NOT_A_CARD )
+ {
+ if( cur_card != NOT_A_CARD )
+ {
+ if( deck[cur_card].next == NOT_A_CARD
+ && deck[cur_card].known == 0 )
+ {
+ /* reveal a hidden card */
deck[cur_card].known = 1;
- } else if(cur_col == REM_COL && cur_rem == NOT_A_CARD) {
+ }
+ else if( cur_col == REM_COL && cur_rem == NOT_A_CARD )
+ {
break;
- /* select a card */
- } else {
+ }
+ else
+ {
+ /* select a card */
sel_card = cur_card;
}
}
- /* unselect card or try putting card on one of the 4 stacks */
- } else if(sel_card == cur_card) {
- move_card(deck[sel_card].suit + COL_NUM, sel_card);
+ }
+ else if( sel_card == cur_card )
+ {
+ /* unselect card or try putting card on
+ * one of the 4 stacks */
+ move_card( deck[sel_card].suit + COL_NUM, sel_card );
sel_card = NOT_A_CARD;
if( cur_col == REM_COL )
{
cur_card = cur_rem;
}
- /* try moving cards */
- } else {
- if(move_card(cur_col, sel_card) == MOVE_OK){
+ }
+ else
+ {
+ /* try moving cards */
+ if( move_card( cur_col, sel_card ) == MOVE_OK )
+ {
sel_card = NOT_A_CARD;
}
}
break;
- /* If the card on the top of the remains can be put where */
- /* the cursor is, go ahead */
+ /* If the card on the top of the remains can be put where
+ * the cursor is, go ahead */
case SOL_REM2CUR:
#ifdef SOL_REM2CUR_PRE
- if(lastbutton != SOL_REM2CUR_PRE)
+ if( lastbutton != SOL_REM2CUR_PRE )
break;
#endif
coun_rem = coun_rem-1;
- move_card(cur_col, cur_rem);
+ move_card( cur_col, cur_rem );
sel_card = NOT_A_CARD;
break;
- /* If the card on top of the remains can be put on one */
- /* of the stacks, do so */
+ /* If the card on top of the remains can be put on one
+ * of the stacks, do so */
case SOL_REM2STACK:
#ifdef SOL_REM2STACK_PRE
- if(lastbutton != SOL_REM2STACK_PRE)
+ if( lastbutton != SOL_REM2STACK_PRE )
break;
#endif
- if(cur_rem != NOT_A_CARD){
- move_card(deck[cur_rem].suit + COL_NUM, cur_rem);
+ if( cur_rem != NOT_A_CARD )
+ {
+ move_card( deck[cur_rem].suit + COL_NUM, cur_rem );
sel_card = NOT_A_CARD;
coun_rem = coun_rem-1;
}
break;
-
#ifdef SOL_REM
case SOL_REM:
- if(sel_card != NOT_A_CARD){
+ if( sel_card != NOT_A_CARD )
+ {
/* unselect selected card */
sel_card = NOT_A_CARD;
break;
}
- if(rem != NOT_A_CARD && cur_rem != NOT_A_CARD) {
- sel_card=cur_rem;
- break;
+ if( rem != NOT_A_CARD && cur_rem != NOT_A_CARD )
+ {
+ sel_card=cur_rem;
+ break;
}
break;
#endif
- /* unselect selected card or ... */
- /* draw new cards from the remains of the deck */
+ /* unselect selected card or ...
+ * draw new cards from the remains of the deck */
case SOL_DRAW:
#ifdef SOL_DRAW_PRE
- if(lastbutton != SOL_DRAW_PRE)
+ if( lastbutton != SOL_DRAW_PRE )
break;
#endif
- if(sel_card != NOT_A_CARD){
+ if( sel_card != NOT_A_CARD )
+ {
/* unselect selected card */
sel_card = NOT_A_CARD;
break;
}
- if(rem != NOT_A_CARD) {
+ if( rem != NOT_A_CARD )
+ {
int cur_rem_old = cur_rem;
coun_rem = 0;
/* draw new cards form the remains of the deck */
- if(cur_rem == NOT_A_CARD){ /*if the cursor card is null*/
+ if( cur_rem == NOT_A_CARD )
+ {
+ /*if the cursor card is null*/
cur_rem = rem;
- i = CARDS_PER_DRAW - 1;
- } else {
- i = CARDS_PER_DRAW;
+ i = cards_per_draw - 1;
+ }
+ else
+ {
+ i = cards_per_draw;
}
- while(i>0 && deck[cur_rem].next != NOT_A_CARD){
+ while( i > 0 && deck[cur_rem].next != NOT_A_CARD )
+ {
cur_rem = deck[cur_rem].next;
i--;
coun_rem = coun_rem +1;
}
- /* test if any cards are really left on */
- /* the remains' stack */
- if(i == CARDS_PER_DRAW){
+ /* test if any cards are really left on
+ * the remains' stack */
+ if( i == cards_per_draw )
+ {
cur_rem = NOT_A_CARD;
coun_rem = 0;
}
/* if cursor was on remains' stack when new cards were
* drawn, put cursor on top of remains' stack */
- if(cur_col == REM_COL && cur_card == cur_rem_old) {
+ if( cur_col == REM_COL && cur_card == cur_rem_old )
+ {
cur_card = cur_rem;
sel_card = NOT_A_CARD;
}
@@ -1476,10 +1485,11 @@ int solitaire(void){
case SOL_RC_QUIT:
#endif
case SOL_QUIT:
-#if LCD_DEPTH>1
- rb->lcd_set_background(LCD_DEFAULT_BG);
+#if LCD_DEPTH > 1
+ rb->lcd_set_background( LCD_DEFAULT_BG );
#endif
- switch(solitaire_menu(MENU_DURINGGAME)){
+ switch( solitaire_menu( MENU_DURINGGAME ) )
+ {
case MENU_QUIT:
return SOLITAIRE_QUIT;
@@ -1490,44 +1500,49 @@ int solitaire(void){
solitaire_init();
break;
}
+ break;
+
default:
- if(rb->default_event_handler(button) == SYS_USB_CONNECTED)
+ if( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
return SOLITAIRE_USB;
break;
}
- if(button != BUTTON_NONE)
+ if( button != BUTTON_NONE )
lastbutton = button;
/* fix incoherences concerning cur_col and cur_card */
- c = find_card_col(cur_card);
- if(c != NOT_A_COL && c != cur_col)
- cur_card = find_last_card(cur_col);
+ c = find_card_col( cur_card );
+ if( c != NOT_A_COL && c != cur_col )
+ cur_card = find_last_card( cur_col );
- if(cur_card == NOT_A_CARD && find_last_card(cur_col) != NOT_A_CARD)
- cur_card = find_last_card(cur_col);
+ if( cur_card == NOT_A_CARD
+ && find_last_card( cur_col ) != NOT_A_CARD )
+ cur_card = find_last_card( cur_col );
}
}
-enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
+/**
+ * Plugin entry point
+ */
+
+enum plugin_status plugin_start( struct plugin_api* api, void* parameter )
{
int result;
/* plugin init */
(void)parameter;
rb = api;
- /* end of plugin init */
- /* Welcome to Solitaire ! */
- rb->splash(HZ, true, "Welcome to Solitaire !");
+ rb->splash( HZ, true, "Welcome to Solitaire!" );
- /* play the game :) */
- /* Keep playing if a game was won (that means display the menu after */
- /* winning instead of quiting) */
- while((result = solitaire()) == SOLITAIRE_WIN);
+ /* play the game :)
+ * Keep playing if a game was won (that means display the menu after
+ * winning instead of quiting) */
+ while( ( result = solitaire() ) == SOLITAIRE_WIN );
/* Exit the plugin */
- return (result == SOLITAIRE_USB) ? PLUGIN_USB_CONNECTED : PLUGIN_OK;
+ return ( result == SOLITAIRE_USB ) ? PLUGIN_USB_CONNECTED : PLUGIN_OK;
}
#endif