2004-08-17 06:50:14 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
2007-09-24 22:19:59 +00:00
|
|
|
* Copyright (C) 2004-2007 Antoine Cellerier <dionoea @t videolan d.t org>
|
2004-08-17 06:50:14 +00:00
|
|
|
*
|
2008-06-28 18:10:04 +00:00
|
|
|
* This program is free software; you can redistribute it and/or
|
|
|
|
* modify it under the terms of the GNU General Public License
|
|
|
|
* as published by the Free Software Foundation; either version 2
|
|
|
|
* of the License, or (at your option) any later version.
|
2004-08-17 06:50:14 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
2006-07-11 21:38:27 +00:00
|
|
|
|
2004-08-17 06:50:14 +00:00
|
|
|
#include "plugin.h"
|
2008-11-20 11:27:31 +00:00
|
|
|
#include "lib/playback_control.h"
|
|
|
|
#include "lib/configfile.h"
|
2009-07-14 13:03:17 +00:00
|
|
|
#include "lib/display_text.h"
|
2004-08-17 06:50:14 +00:00
|
|
|
#include "button.h"
|
|
|
|
#include "lcd.h"
|
|
|
|
|
|
|
|
#define min(a,b) (a<b?a:b)
|
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/**
|
|
|
|
* Key definitions
|
|
|
|
*/
|
2005-12-20 22:57:04 +00:00
|
|
|
|
2020-07-15 23:40:55 +00:00
|
|
|
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
|
|
|
|
(CONFIG_KEYPAD == IRIVER_H300_PAD)
|
2006-08-02 22:17:21 +00:00
|
|
|
# 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)
|
2006-10-01 20:02:44 +00:00
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_SELECT
|
2006-08-02 22:17:21 +00:00
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_ON)
|
|
|
|
# define SOL_REM BUTTON_REC
|
|
|
|
# define SOL_RC_QUIT BUTTON_RC_STOP
|
2006-09-06 08:28:13 +00:00
|
|
|
# define HK_MOVE "NAVI"
|
|
|
|
# define HK_DRAW "A-B"
|
2006-08-02 22:17:21 +00:00
|
|
|
# define HK_REM2CUR "PLAY+LEFT"
|
2006-09-17 22:14:18 +00:00
|
|
|
# define HK_CUR2STACK "NAVI.."
|
2006-08-02 22:17:21 +00:00
|
|
|
# define HK_REM2STACK "PLAY+RIGHT"
|
2005-02-16 02:08:16 +00:00
|
|
|
|
2007-07-27 09:57:27 +00:00
|
|
|
#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD) || \
|
|
|
|
(CONFIG_KEYPAD == IPOD_1G2G_PAD)
|
2006-08-02 22:17:21 +00:00
|
|
|
# define SOL_QUIT (BUTTON_SELECT | BUTTON_MENU)
|
2006-09-17 22:14:18 +00:00
|
|
|
# define SOL_UP BUTTON_SCROLL_BACK
|
|
|
|
# define SOL_DOWN BUTTON_SCROLL_FWD
|
|
|
|
# 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_SELECT
|
|
|
|
# define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
|
|
|
|
# define SOL_DRAW_PRE BUTTON_MENU
|
|
|
|
# define SOL_DRAW (BUTTON_MENU | BUTTON_REL)
|
|
|
|
# define SOL_REM2CUR BUTTON_PLAY
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_MENU
|
|
|
|
# define SOL_CUR2STACK (BUTTON_MENU | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK_PRE BUTTON_RIGHT
|
|
|
|
# define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_REPEAT)
|
2006-09-18 00:36:09 +00:00
|
|
|
# define HK_UD "SCROLL U/D"
|
2006-08-02 22:17:21 +00:00
|
|
|
# define HK_MOVE "SELECT"
|
2006-09-17 22:14:18 +00:00
|
|
|
# define HK_DRAW "MENU"
|
|
|
|
# define HK_REM2CUR "PLAY"
|
|
|
|
# define HK_CUR2STACK "MENU.."
|
|
|
|
# define HK_REM2STACK "RIGHT.."
|
2006-07-11 21:38:27 +00:00
|
|
|
|
2007-03-16 23:02:39 +00:00
|
|
|
#elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD)
|
2006-10-18 21:39:57 +00:00
|
|
|
# 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_PRE BUTTON_SELECT
|
|
|
|
# define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
|
|
|
|
# define SOL_DRAW_PRE BUTTON_PLAY
|
|
|
|
# define SOL_DRAW (BUTTON_PLAY | BUTTON_REL)
|
|
|
|
# define SOL_REM2CUR_PRE BUTTON_PLAY
|
|
|
|
# define SOL_REM2CUR (BUTTON_PLAY | BUTTON_REPEAT)
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_SELECT
|
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_REC
|
|
|
|
# define HK_MOVE "SELECT"
|
|
|
|
# define HK_DRAW "PLAY"
|
|
|
|
# define HK_REM2CUR "PLAY.."
|
|
|
|
# define HK_CUR2STACK "SELECT.."
|
|
|
|
# define HK_REM2STACK "REC"
|
2006-02-24 15:42:52 +00:00
|
|
|
|
2006-07-11 21:38:27 +00:00
|
|
|
#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
|
2007-05-19 23:38:09 +00:00
|
|
|
# define SOL_QUIT BUTTON_POWER
|
2006-08-02 22:17:21 +00:00
|
|
|
# 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
|
2007-05-19 23:38:09 +00:00
|
|
|
# define SOL_REM2CUR (BUTTON_LEFT | BUTTON_A)
|
2006-08-02 22:17:21 +00:00
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
2007-05-19 23:38:09 +00:00
|
|
|
# define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_A)
|
2006-08-02 22:17:21 +00:00
|
|
|
# define HK_MOVE "SELECT"
|
|
|
|
# define HK_DRAW "MENU"
|
2007-05-19 23:38:09 +00:00
|
|
|
# define HK_REM2CUR "A+LEFT"
|
2006-08-02 22:17:21 +00:00
|
|
|
# define HK_CUR2STACK "SELECT.."
|
2007-05-19 23:38:09 +00:00
|
|
|
# define HK_REM2STACK "A+RIGHT"
|
2006-07-11 21:38:27 +00:00
|
|
|
|
2006-10-26 13:38:09 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_E200_PAD)
|
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_UP
|
|
|
|
# define SOL_DOWN BUTTON_DOWN
|
2008-01-10 08:08:31 +00:00
|
|
|
# define SOL_LEFT BUTTON_SCROLL_BACK
|
|
|
|
# define SOL_RIGHT BUTTON_SCROLL_FWD
|
2007-01-03 23:53:22 +00:00
|
|
|
# define SOL_MOVE BUTTON_SELECT
|
|
|
|
# define SOL_DRAW BUTTON_REC
|
|
|
|
# define SOL_REM2CUR BUTTON_LEFT
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_REC
|
|
|
|
# define SOL_CUR2STACK (BUTTON_REC | BUTTON_RIGHT)
|
|
|
|
# define SOL_REM2STACK BUTTON_RIGHT
|
2006-10-26 13:38:09 +00:00
|
|
|
# define HK_MOVE "SELECT"
|
2007-09-20 10:49:48 +00:00
|
|
|
# define HK_DRAW "REC"
|
|
|
|
# define HK_REM2CUR "LEFT"
|
|
|
|
# define HK_CUR2STACK "DOUBLE SELECT"
|
|
|
|
# define HK_REM2STACK "RIGHT"
|
|
|
|
|
2009-01-04 23:33:15 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
|
2009-04-10 17:28:26 +00:00
|
|
|
# define SOL_QUIT (BUTTON_HOME|BUTTON_REPEAT)
|
2009-01-04 23:33:15 +00:00
|
|
|
# define SOL_UP BUTTON_UP
|
|
|
|
# define SOL_DOWN BUTTON_DOWN
|
|
|
|
# define SOL_LEFT BUTTON_SCROLL_BACK
|
|
|
|
# define SOL_RIGHT BUTTON_SCROLL_FWD
|
|
|
|
# define SOL_MOVE (BUTTON_SELECT|BUTTON_REL)
|
2009-07-05 16:13:20 +00:00
|
|
|
# define SOL_DRAW (BUTTON_HOME|BUTTON_REL)
|
2009-01-04 23:33:15 +00:00
|
|
|
# define SOL_REM2CUR BUTTON_LEFT
|
|
|
|
# define SOL_CUR2STACK_PRE (BUTTON_RIGHT | BUTTON_REPEAT)
|
|
|
|
# define SOL_CUR2STACK BUTTON_RIGHT
|
|
|
|
# define SOL_REM2STACK (BUTTON_LEFT|BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK_PRE BUTTON_LEFT
|
2009-07-05 16:13:20 +00:00
|
|
|
# define HK_MOVE "SHORT SELECT"
|
|
|
|
# define HK_DRAW "SHORT HOME"
|
2009-01-04 23:33:15 +00:00
|
|
|
# define HK_REM2CUR "LEFT"
|
|
|
|
# define HK_CUR2STACK "DOUBLE SELECT"
|
2009-07-05 16:13:20 +00:00
|
|
|
# define HK_REM2STACK "LEFT"
|
2009-01-04 23:33:15 +00:00
|
|
|
|
2007-09-20 10:49:48 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_C200_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_PRE BUTTON_SELECT
|
|
|
|
# define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
|
|
|
|
# define SOL_DRAW BUTTON_VOL_DOWN
|
|
|
|
# define SOL_REM2CUR BUTTON_REC
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_SELECT
|
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_VOL_UP
|
|
|
|
# define HK_MOVE "SELECT"
|
2007-01-03 23:53:22 +00:00
|
|
|
# define HK_DRAW "REC"
|
|
|
|
# define HK_REM2CUR "LEFT"
|
|
|
|
# define HK_CUR2STACK "DOUBLE SELECT"
|
|
|
|
# define HK_REM2STACK "RIGHT"
|
2006-10-26 13:38:09 +00:00
|
|
|
|
2008-11-28 00:37:28 +00:00
|
|
|
#elif CONFIG_KEYPAD == SANSA_CLIP_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_PRE BUTTON_SELECT
|
|
|
|
# define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
|
|
|
|
# define SOL_DRAW BUTTON_HOME
|
|
|
|
# define SOL_REM2CUR BUTTON_VOL_DOWN
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_SELECT
|
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_VOL_UP
|
|
|
|
# define HK_MOVE "SELECT"
|
|
|
|
# define HK_DRAW "HOME"
|
|
|
|
# define HK_REM2CUR "LEFT"
|
|
|
|
# define HK_CUR2STACK "DOUBLE SELECT"
|
|
|
|
# define HK_REM2STACK "RIGHT"
|
|
|
|
|
2008-12-12 19:50:49 +00:00
|
|
|
#elif CONFIG_KEYPAD == SANSA_M200_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_PRE BUTTON_SELECT
|
|
|
|
# define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
|
|
|
|
# define SOL_DRAW (BUTTON_SELECT | BUTTON_UP)
|
|
|
|
# define SOL_REM2CUR BUTTON_VOL_DOWN
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_SELECT
|
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_VOL_UP
|
|
|
|
# define HK_MOVE "SELECT"
|
|
|
|
# define HK_DRAW "SELECT + UP"
|
|
|
|
# define HK_REM2CUR "LEFT"
|
|
|
|
# define HK_CUR2STACK "DOUBLE SELECT"
|
|
|
|
# define HK_REM2STACK "RIGHT"
|
|
|
|
|
2006-08-11 08:35:27 +00:00
|
|
|
#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
|
2006-10-18 21:39:57 +00:00
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_SCROLL_UP
|
|
|
|
# define SOL_DOWN BUTTON_SCROLL_DOWN
|
|
|
|
# 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 BUTTON_PLAY
|
|
|
|
# define SOL_DRAW_PRE BUTTON_LEFT
|
|
|
|
# define SOL_DRAW (BUTTON_LEFT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2CUR BUTTON_FF
|
|
|
|
# define SOL_CUR2STACK BUTTON_REW
|
|
|
|
# define SOL_REM2STACK_PRE BUTTON_RIGHT
|
|
|
|
# define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_REPEAT)
|
|
|
|
# define HK_MOVE "PLAY"
|
|
|
|
# define HK_DRAW "LEFT.."
|
|
|
|
# define HK_REM2CUR "FF"
|
|
|
|
# define HK_CUR2STACK "REW"
|
|
|
|
# define HK_REM2STACK "RIGHT.."
|
2006-08-11 08:35:27 +00:00
|
|
|
|
2008-02-17 12:23:02 +00:00
|
|
|
#elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
|
|
|
|
# define SOL_QUIT BUTTON_BACK
|
|
|
|
# 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_SELECT)
|
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_SELECT)
|
|
|
|
# define HK_MOVE "SELECT"
|
|
|
|
# define HK_DRAW "MENU"
|
|
|
|
# define HK_REM2CUR "SELECT+LEFT"
|
|
|
|
# define HK_CUR2STACK "SELECT.."
|
|
|
|
# define HK_REM2STACK "SELECT+RIGHT"
|
|
|
|
|
2008-03-01 22:55:09 +00:00
|
|
|
#elif (CONFIG_KEYPAD == MROBE100_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_PRE BUTTON_SELECT
|
|
|
|
# define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
|
|
|
|
# define SOL_DRAW BUTTON_MENU
|
|
|
|
# define SOL_REM2CUR (BUTTON_LEFT | BUTTON_DISPLAY)
|
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_DISPLAY)
|
|
|
|
# define HK_MOVE "SELECT"
|
|
|
|
# define HK_DRAW "MENU"
|
|
|
|
# define HK_REM2CUR "DISPLAY+LEFT"
|
|
|
|
# define HK_CUR2STACK "SELECT.."
|
|
|
|
# define HK_REM2STACK "DISPLAY+RIGHT"
|
|
|
|
|
2008-03-22 10:24:28 +00:00
|
|
|
#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
|
|
|
|
# define SOL_QUIT BUTTON_RC_REC
|
|
|
|
# define SOL_UP BUTTON_RC_VOL_UP
|
|
|
|
# define SOL_DOWN BUTTON_RC_VOL_DOWN
|
|
|
|
# define SOL_LEFT BUTTON_RC_REW
|
|
|
|
# define SOL_RIGHT BUTTON_RC_FF
|
|
|
|
# define SOL_MOVE BUTTON_RC_PLAY
|
|
|
|
# define SOL_DRAW_PRE BUTTON_RC_MENU
|
|
|
|
# define SOL_DRAW (BUTTON_RC_MENU | BUTTON_REL)
|
|
|
|
# define SOL_REM2CUR_PRE BUTTON_RC_MENU
|
|
|
|
# define SOL_REM2CUR (BUTTON_RC_MENU | BUTTON_REPEAT)
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_RC_MODE
|
|
|
|
# define SOL_CUR2STACK (BUTTON_RC_MODE | BUTTON_REL)
|
|
|
|
# define SOL_REM2STACK_PRE BUTTON_RC_MODE
|
|
|
|
# define SOL_REM2STACK (BUTTON_RC_MODE | BUTTON_REPEAT)
|
|
|
|
# define HK_LR "REW/FF"
|
|
|
|
# define HK_UD "VOL UP/DOWN"
|
|
|
|
# define HK_MOVE "PLAY"
|
|
|
|
# define HK_DRAW "MENU"
|
|
|
|
# define HK_REM2CUR "MENU.."
|
|
|
|
# define HK_CUR2STACK "MODE"
|
|
|
|
# define HK_REM2STACK "MODE.."
|
|
|
|
|
2009-12-15 20:51:41 +00:00
|
|
|
#elif (CONFIG_KEYPAD == COWON_D2_PAD)
|
2008-03-22 22:03:34 +00:00
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
|
2008-12-04 21:28:56 +00:00
|
|
|
#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
|
|
|
|
# define SOL_QUIT BUTTON_BACK
|
|
|
|
# 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_SELECT)
|
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_SELECT)
|
2008-12-08 09:51:42 +00:00
|
|
|
# define HK_MOVE "MIDDLE"
|
2008-12-04 21:28:56 +00:00
|
|
|
# define HK_DRAW "MENU"
|
|
|
|
# define HK_REM2CUR "PLAY+LEFT"
|
|
|
|
# define HK_CUR2STACK "PLAY.."
|
|
|
|
# define HK_REM2STACK "PLAY+RIGHT"
|
|
|
|
|
2014-03-21 21:16:02 +00:00
|
|
|
#elif (CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD)
|
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_UP
|
|
|
|
# define SOL_DOWN BUTTON_DOWN
|
|
|
|
# define SOL_LEFT BUTTON_BACK
|
|
|
|
# define SOL_RIGHT BUTTON_MENU
|
|
|
|
# define SOL_MOVE (BUTTON_PLAY|BUTTON_REL)
|
|
|
|
# define SOL_DRAW (BUTTON_PLAY|BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2CUR BUTTON_VOL_DOWN
|
|
|
|
# define SOL_CUR2STACK_PRE (BUTTON_VOL_UP | BUTTON_REPEAT)
|
|
|
|
# define SOL_CUR2STACK BUTTON_VOL_UP
|
|
|
|
# define SOL_REM2STACK (BUTTON_VOL_DOWN|BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK_PRE BUTTON_VOL_DOWN
|
|
|
|
|
|
|
|
# define HK_MOVE "SHORT PLAY"
|
|
|
|
# define HK_DRAW "LONG PLAY"
|
|
|
|
# define HK_REM2CUR "VOLUME-"
|
|
|
|
# define HK_CUR2STACK "VOLUME+"
|
|
|
|
# define HK_REM2STACK "LONG VOLUME-"
|
|
|
|
|
2009-01-24 22:41:55 +00:00
|
|
|
#elif CONFIG_KEYPAD == PHILIPS_HDD1630_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_PRE BUTTON_SELECT
|
|
|
|
# define SOL_MOVE (BUTTON_SELECT | BUTTON_REL)
|
|
|
|
# define SOL_DRAW BUTTON_MENU
|
|
|
|
# define SOL_REM2CUR (BUTTON_LEFT | BUTTON_VIEW)
|
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK (BUTTON_RIGHT | BUTTON_VIEW)
|
2010-11-02 03:29:16 +00:00
|
|
|
# define HK_MOVE "SELECT"
|
|
|
|
# define HK_DRAW "MENU"
|
|
|
|
# define HK_REM2CUR "VIEW+LEFT"
|
|
|
|
# define HK_CUR2STACK "SELECT.."
|
|
|
|
# define HK_REM2STACK "VIEW+RIGHT"
|
|
|
|
|
|
|
|
#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
|
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_UP
|
|
|
|
# define SOL_DOWN BUTTON_DOWN
|
|
|
|
# define SOL_LEFT BUTTON_PREV
|
|
|
|
# define SOL_RIGHT BUTTON_NEXT
|
|
|
|
# define SOL_MOVE_PRE BUTTON_PLAY
|
|
|
|
# define SOL_MOVE (BUTTON_PLAY | BUTTON_REL)
|
|
|
|
# define SOL_DRAW BUTTON_MENU
|
|
|
|
# define SOL_REM2CUR BUTTON_LEFT
|
|
|
|
# define SOL_CUR2STACK (BUTTON_PLAY | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_RIGHT
|
|
|
|
# define HK_MOVE "PLAY"
|
|
|
|
# define HK_DRAW "MENU"
|
|
|
|
# define HK_REM2CUR "LEFT"
|
|
|
|
# define HK_CUR2STACK "PLAY.."
|
|
|
|
# define HK_REM2STACK "RIGHT"
|
2009-01-24 22:41:55 +00:00
|
|
|
|
2009-12-07 18:23:25 +00:00
|
|
|
#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
|
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_UP
|
|
|
|
# define SOL_DOWN BUTTON_DOWN
|
|
|
|
# define SOL_LEFT BUTTON_PREV
|
|
|
|
# define SOL_RIGHT BUTTON_NEXT
|
|
|
|
# define SOL_MOVE_PRE BUTTON_PLAY
|
|
|
|
# define SOL_MOVE (BUTTON_PLAY | BUTTON_REL)
|
|
|
|
# define SOL_DRAW BUTTON_MENU
|
|
|
|
# define SOL_REM2CUR BUTTON_LEFT
|
|
|
|
# define SOL_CUR2STACK (BUTTON_PLAY | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_RIGHT
|
|
|
|
# define HK_MOVE "PLAY"
|
|
|
|
# define HK_DRAW "MENU"
|
|
|
|
# define HK_REM2CUR "LEFT"
|
|
|
|
# define HK_CUR2STACK "PLAY..."
|
2010-02-13 15:46:34 +00:00
|
|
|
# define HK_REM2STACK "RIGHT"
|
2009-12-07 18:23:25 +00:00
|
|
|
|
2009-08-31 21:11:32 +00:00
|
|
|
#elif (CONFIG_KEYPAD == ONDAVX747_PAD) || \
|
|
|
|
(CONFIG_KEYPAD == ONDAVX777_PAD) || \
|
|
|
|
CONFIG_KEYPAD == MROBE500_PAD
|
2009-04-07 23:41:44 +00:00
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
|
2015-07-19 23:50:26 +00:00
|
|
|
#elif CONFIG_KEYPAD == SAMSUNG_YH820_PAD
|
|
|
|
# define SOL_QUIT BUTTON_REW
|
2009-08-04 03:08:32 +00:00
|
|
|
# define SOL_UP BUTTON_UP
|
|
|
|
# define SOL_DOWN BUTTON_DOWN
|
2014-10-15 12:25:28 +00:00
|
|
|
# define SOL_LEFT BUTTON_LEFT
|
|
|
|
# define SOL_RIGHT BUTTON_RIGHT
|
2009-08-04 03:08:32 +00:00
|
|
|
# define SOL_MOVE BUTTON_PLAY
|
2014-10-15 12:25:28 +00:00
|
|
|
# define SOL_DRAW BUTTON_FFWD
|
2015-07-19 23:50:26 +00:00
|
|
|
# define SOL_REM2CUR (BUTTON_REC | BUTTON_DOWN)
|
|
|
|
# define SOL_CUR2STACK (BUTTON_REC | BUTTON_UP)
|
|
|
|
# define SOL_REM2STACK (BUTTON_REC | BUTTON_RIGHT)
|
2009-08-04 03:08:32 +00:00
|
|
|
# define HK_MOVE "PLAY"
|
2015-07-19 23:50:26 +00:00
|
|
|
# define HK_DRAW "FFWD"
|
|
|
|
# define HK_REM2CUR "REC+DOWN"
|
|
|
|
# define HK_CUR2STACK "REC+UP"
|
|
|
|
# define HK_REM2STACK "REC+RIGHT"
|
|
|
|
|
2016-01-23 14:54:08 +00:00
|
|
|
#elif CONFIG_KEYPAD == SAMSUNG_YH92X_PAD
|
2015-07-19 23:50:26 +00:00
|
|
|
# define SOL_QUIT BUTTON_REW
|
|
|
|
# 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_PLAY
|
|
|
|
# define SOL_MOVE (BUTTON_PLAY | BUTTON_REL)
|
|
|
|
# define SOL_DRAW BUTTON_FFWD
|
|
|
|
# define SOL_REM2CUR (BUTTON_PLAY | BUTTON_DOWN)
|
|
|
|
# define SOL_CUR2STACK (BUTTON_PLAY | BUTTON_UP)
|
|
|
|
# define SOL_REM2STACK (BUTTON_PLAY | BUTTON_RIGHT)
|
|
|
|
# define HK_MOVE "PLAY"
|
|
|
|
# define HK_DRAW "FFWD"
|
|
|
|
# define HK_REM2CUR "PLAY+DOWN"
|
|
|
|
# define HK_CUR2STACK "PLAY+UP"
|
|
|
|
# define HK_REM2STACK "PLAY+RIGHT"
|
2009-08-04 03:08:32 +00:00
|
|
|
|
2010-02-13 15:46:34 +00:00
|
|
|
#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
|
|
|
|
# define SOL_QUIT BUTTON_REC
|
|
|
|
# define SOL_UP BUTTON_UP
|
|
|
|
# define SOL_DOWN BUTTON_DOWN
|
|
|
|
# define SOL_LEFT BUTTON_PREV
|
|
|
|
# define SOL_RIGHT BUTTON_NEXT
|
|
|
|
# define SOL_MOVE_PRE BUTTON_OK
|
|
|
|
# define SOL_MOVE (BUTTON_OK | BUTTON_REL)
|
|
|
|
# define SOL_DRAW BUTTON_MENU
|
|
|
|
# define SOL_REM2CUR BUTTON_CANCEL
|
|
|
|
# define SOL_CUR2STACK BUTTON_PLAY
|
|
|
|
# define SOL_REM2STACK (BUTTON_PLAY | BUTTON_REPEAT)
|
|
|
|
# define HK_MOVE "OK"
|
|
|
|
# define HK_DRAW "MENU"
|
|
|
|
# define HK_REM2CUR "CANCEL"
|
|
|
|
# define HK_CUR2STACK "PLAY"
|
|
|
|
# define HK_REM2STACK "PLAY..."
|
|
|
|
|
2010-04-26 21:40:00 +00:00
|
|
|
#elif CONFIG_KEYPAD == MPIO_HD200_PAD
|
|
|
|
# define SOL_QUIT (BUTTON_REC | BUTTON_PLAY)
|
2010-11-02 10:44:34 +00:00
|
|
|
# define SOL_UP BUTTON_REW
|
|
|
|
# define SOL_DOWN BUTTON_FF
|
2010-04-26 21:40:00 +00:00
|
|
|
# define SOL_LEFT BUTTON_VOL_DOWN
|
|
|
|
# define SOL_RIGHT BUTTON_VOL_UP
|
2010-11-02 10:44:34 +00:00
|
|
|
# define SOL_MOVE_PRE BUTTON_FUNC
|
|
|
|
# define SOL_MOVE (BUTTON_FUNC | BUTTON_REL)
|
2010-04-26 21:40:00 +00:00
|
|
|
# define SOL_DRAW BUTTON_REC
|
|
|
|
# define SOL_REM2CUR (BUTTON_REC | BUTTON_REPEAT)
|
|
|
|
# define SOL_CUR2STACK BUTTON_PLAY
|
|
|
|
# define SOL_REM2STACK (BUTTON_PLAY | BUTTON_REPEAT)
|
2010-11-02 10:44:34 +00:00
|
|
|
# define HK_MOVE "FUNC"
|
2010-04-26 21:40:00 +00:00
|
|
|
# define HK_DRAW "REC"
|
|
|
|
# define HK_REM2CUR "REC.."
|
|
|
|
# define HK_CUR2STACK "PLAY"
|
|
|
|
# define HK_REM2STACK "PLAY...."
|
|
|
|
|
2010-11-30 10:52:14 +00:00
|
|
|
#elif CONFIG_KEYPAD == MPIO_HD300_PAD
|
2012-02-02 13:42:42 +00:00
|
|
|
# define SOL_QUIT (BUTTON_MENU | BUTTON_REPEAT)
|
2010-11-30 10:52:14 +00:00
|
|
|
# define SOL_UP BUTTON_UP
|
|
|
|
# define SOL_DOWN BUTTON_DOWN
|
2012-02-02 13:42:42 +00:00
|
|
|
# define SOL_LEFT BUTTON_REW
|
|
|
|
# define SOL_RIGHT BUTTON_FF
|
|
|
|
# define SOL_MOVE_PRE BUTTON_ENTER
|
|
|
|
# define SOL_MOVE (BUTTON_ENTER | BUTTON_REL)
|
|
|
|
# define SOL_DRAW BUTTON_MENU
|
|
|
|
# define SOL_REM2CUR (BUTTON_PLAY | BUTTON_REL)
|
|
|
|
# define SOL_CUR2STACK BUTTON_REC
|
2010-11-30 10:52:14 +00:00
|
|
|
# define SOL_REM2STACK (BUTTON_PLAY | BUTTON_REPEAT)
|
2012-02-02 13:42:42 +00:00
|
|
|
# define HK_MOVE "ENTER"
|
|
|
|
# define HK_DRAW "MENU"
|
|
|
|
# define HK_REM2CUR "PLAY"
|
|
|
|
# define HK_CUR2STACK "ENTER..."
|
2010-11-30 10:52:14 +00:00
|
|
|
# define HK_REM2STACK "PLAY...."
|
|
|
|
|
2011-10-02 16:21:08 +00:00
|
|
|
#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
|
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_UP
|
|
|
|
# define SOL_DOWN BUTTON_DOWN
|
2012-03-01 22:23:29 +00:00
|
|
|
# define SOL_LEFT BUTTON_LEFT
|
|
|
|
# define SOL_RIGHT BUTTON_RIGHT
|
|
|
|
# define SOL_MOVE BUTTON_SELECT
|
|
|
|
# define SOL_DRAW BUTTON_BACK
|
|
|
|
# define SOL_REM2CUR BUTTON_BOTTOMLEFT
|
|
|
|
# define SOL_CUR2STACK BUTTON_PLAYPAUSE|BUTTON_REL
|
|
|
|
# define SOL_REM2STACK BUTTON_PLAYPAUSE|BUTTON_REPEAT
|
|
|
|
# define HK_MOVE "SELECT"
|
|
|
|
# define HK_DRAW "BACK"
|
|
|
|
# define HK_REM2CUR "BOTTOM-LEFT"
|
|
|
|
# define HK_CUR2STACK "PLAY-PAUSE"
|
|
|
|
# define HK_REM2STACK "BOTTOM-RIGHT"
|
2011-10-02 16:21:08 +00:00
|
|
|
|
2011-11-16 14:08:01 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_CONNECT_PAD)
|
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_UP
|
|
|
|
# define SOL_DOWN BUTTON_DOWN
|
|
|
|
# define SOL_LEFT BUTTON_SCROLL_BACK
|
|
|
|
# define SOL_RIGHT BUTTON_SCROLL_FWD
|
|
|
|
# define SOL_MOVE BUTTON_SELECT
|
|
|
|
# define SOL_DRAW BUTTON_VOL_UP
|
|
|
|
# define SOL_REM2CUR BUTTON_LEFT
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_VOL_DOWN
|
|
|
|
# define SOL_CUR2STACK BUTTON_NEXT
|
|
|
|
# define SOL_REM2STACK BUTTON_PREV
|
|
|
|
# define HK_MOVE "SELECT"
|
|
|
|
# define HK_DRAW "Vol+"
|
|
|
|
# define HK_REM2CUR "LEFT"
|
|
|
|
# define HK_CUR2STACK "NEXT"
|
|
|
|
# define HK_REM2STACK "PREV"
|
|
|
|
|
Initial commit of the Samsung YP-R0 port.
This port is a hybrid native/RaaA port. It runs on a embedded linux system,
but is the only application. It therefore can implement lots of stuff that
native targets also implement, while leveraging the underlying linux kernel.
The port is quite advanced. User interface, audio playback, plugins work
mostly fine. Missing is e.g. power mangement and USB (see SamsungYPR0 wiki page).
Included in utils/ypr0tools are scripts and programs required to generate
a patched firmware. The patched firmware has the rootfs modified to load
Rockbox. It includes a early/safe USB mode.
This port needs a new toolchain, one that includes glibc headers and libraries.
rockboxdev.sh can generate it, but e.g. codesourcey and distro packages may
also work.
Most of the initial effort is done by Lorenzo Miori and others (on ABI),
including reverse engineering and patching of the original firmware,
initial drivers, and more. Big thanks to you.
Flyspray: FS#12348
Author: Lorenzo Miori, myself
Merry christmas to ypr0 owners! :)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31415 a1c6a512-1295-4272-9138-f99709370657
2011-12-24 11:56:46 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SAMSUNG_YPR0_PAD)
|
|
|
|
# define SOL_QUIT BUTTON_BACK
|
|
|
|
# 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_USER | BUTTON_REPEAT)
|
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_POWER
|
|
|
|
# define HK_MOVE "Select"
|
|
|
|
# define HK_DRAW "Menu"
|
|
|
|
# define HK_REM2CUR "Long User"
|
|
|
|
# define HK_CUR2STACK "Long Select.."
|
|
|
|
# define HK_REM2STACK "Power"
|
|
|
|
|
2012-03-23 18:32:50 +00:00
|
|
|
#elif (CONFIG_KEYPAD == HM60X_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_PRE BUTTON_SELECT
|
|
|
|
# define SOL_MOVE (BUTTON_POWER | BUTTON_SELECT)
|
|
|
|
# define SOL_DRAW (BUTTON_POWER | BUTTON_UP)
|
|
|
|
# define SOL_REM2CUR (BUTTON_POWER | BUTTON_DOWN)
|
|
|
|
# define SOL_CUR2STACK (BUTTON_POWER | BUTTON_LEFT)
|
|
|
|
# define SOL_REM2STACK (BUTTON_POWER | BUTTON_RIGHT)
|
|
|
|
# define HK_MOVE "SELECT + POWER"
|
|
|
|
# define HK_DRAW "UP + POWER"
|
|
|
|
# define HK_REM2CUR "DOWN + POWER"
|
|
|
|
# define HK_CUR2STACK "LEFT + POWER"
|
|
|
|
# define HK_REM2STACK "RIGHT + POWER"
|
|
|
|
|
2012-04-06 16:17:27 +00:00
|
|
|
#elif (CONFIG_KEYPAD == HM801_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_PRE BUTTON_PREV
|
|
|
|
# define SOL_MOVE BUTTON_NEXT
|
|
|
|
# define SOL_DRAW BUTTON_PLAY
|
|
|
|
# define SOL_REM2CUR BUTTON_SELECT
|
|
|
|
# define SOL_CUR2STACK (BUTTON_POWER | BUTTON_LEFT)
|
|
|
|
# define SOL_REM2STACK (BUTTON_POWER | BUTTON_RIGHT)
|
|
|
|
# define HK_MOVE "PREV"
|
|
|
|
# define HK_DRAW "PLAY"
|
|
|
|
# define HK_REM2CUR "SELECT"
|
|
|
|
# define HK_CUR2STACK "POWER + LEFT"
|
|
|
|
# define HK_REM2STACK "POWER + RIGHT"
|
|
|
|
|
2014-06-30 18:24:15 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SONY_NWZ_PAD)
|
|
|
|
#define SOL_QUIT BUTTON_BACK
|
|
|
|
#define SOL_UP BUTTON_UP
|
|
|
|
#define SOL_DOWN BUTTON_DOWN
|
|
|
|
#define SOL_LEFT BUTTON_LEFT
|
|
|
|
#define SOL_RIGHT BUTTON_RIGHT
|
|
|
|
#define SOL_MOVE BUTTON_PLAY
|
|
|
|
#define SOL_DRAW (BUTTON_POWER|BUTTON_UP)
|
|
|
|
#define SOL_REM2CUR (BUTTON_POWER|BUTTON_DOWN)
|
|
|
|
#define SOL_CUR2STACK (BUTTON_POWER|BUTTON_LEFT)
|
|
|
|
#define SOL_REM2STACK (BUTTON_POWER|BUTTON_RIGHT)
|
|
|
|
#define HK_MOVE "Play"
|
|
|
|
#define HK_DRAW "Option+Up"
|
|
|
|
#define HK_REM2CUR "Option+Down"
|
|
|
|
#define HK_CUR2STACK "Option+Left"
|
|
|
|
#define HK_REM2STACK "Option+Right"
|
|
|
|
|
2018-03-02 20:53:55 +00:00
|
|
|
#elif (CONFIG_KEYPAD == AGPTEK_ROCKER_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_VOLUP|BUTTON_UP)
|
|
|
|
#define SOL_REM2CUR (BUTTON_VOLUP|BUTTON_DOWN)
|
|
|
|
#define SOL_CUR2STACK (BUTTON_VOLUP|BUTTON_LEFT)
|
|
|
|
#define SOL_REM2STACK (BUTTON_VOLUP|BUTTON_RIGHT)
|
|
|
|
#define HK_MOVE "Select"
|
|
|
|
#define HK_DRAW "Option+Up"
|
|
|
|
#define HK_REM2CUR "Option+Down"
|
|
|
|
#define HK_CUR2STACK "Option+Left"
|
|
|
|
#define HK_REM2STACK "Option+Right"
|
|
|
|
|
2014-07-17 08:40:17 +00:00
|
|
|
#elif (CONFIG_KEYPAD == CREATIVE_ZEN_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_PLAYPAUSE
|
|
|
|
#define SOL_REM2CUR BUTTON_BACK
|
|
|
|
#define SOL_CUR2STACK BUTTON_MENU
|
|
|
|
#define SOL_REM2STACK BUTTON_SHORTCUT
|
|
|
|
#define HK_MOVE "Select"
|
|
|
|
#define HK_DRAW "Play/pause"
|
|
|
|
#define HK_REM2CUR "Back"
|
|
|
|
#define HK_CUR2STACK "Menu"
|
|
|
|
#define HK_REM2STACK "Shortcut"
|
|
|
|
|
2014-08-30 11:15:53 +00:00
|
|
|
#elif (CONFIG_KEYPAD == DX50_PAD)
|
|
|
|
# define SOL_QUIT (BUTTON_POWER | BUTTON_REL)
|
|
|
|
|
2018-02-22 22:42:29 +00:00
|
|
|
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
|
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
|
2018-06-28 10:24:26 +00:00
|
|
|
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
|
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_HOME
|
|
|
|
# define SOL_DOWN BUTTON_OPTION
|
|
|
|
# define SOL_LEFT BUTTON_PREV
|
|
|
|
# define SOL_RIGHT BUTTON_NEXT
|
|
|
|
# define SOL_MOVE_PRE BUTTON_PLAY
|
|
|
|
# define SOL_MOVE (BUTTON_PLAY | BUTTON_REL)
|
|
|
|
# define SOL_DRAW (BUTTON_POWER | BUTTON_REPEAT)
|
2018-11-05 12:01:55 +00:00
|
|
|
# define SOL_REM2CUR BUTTON_VOL_DOWN
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_PLAY
|
|
|
|
# define SOL_CUR2STACK (BUTTON_PLAY | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_VOL_UP
|
|
|
|
# define HK_MOVE "PLAY"
|
|
|
|
# define HK_DRAW "DBL HOME"
|
|
|
|
# define HK_REM2CUR "PREV"
|
|
|
|
# define HK_CUR2STACK "DBL PLAY"
|
|
|
|
# define HK_REM2STACK "NEXT"
|
|
|
|
|
2020-10-08 13:47:40 +00:00
|
|
|
#elif CONFIG_KEYPAD == XDUOO_X3II_PAD || CONFIG_KEYPAD == XDUOO_X20_PAD
|
2018-11-05 12:01:55 +00:00
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_HOME
|
|
|
|
# define SOL_DOWN BUTTON_OPTION
|
|
|
|
# define SOL_LEFT BUTTON_PREV
|
|
|
|
# define SOL_RIGHT BUTTON_NEXT
|
|
|
|
# define SOL_MOVE_PRE BUTTON_PLAY
|
|
|
|
# define SOL_MOVE (BUTTON_PLAY | BUTTON_REL)
|
|
|
|
# define SOL_DRAW (BUTTON_POWER | BUTTON_REPEAT)
|
2018-06-28 10:24:26 +00:00
|
|
|
# define SOL_REM2CUR BUTTON_VOL_DOWN
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_PLAY
|
2020-10-03 22:17:11 +00:00
|
|
|
# define SOL_CUR2STACK (BUTTON_PLAY | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_VOL_UP
|
|
|
|
# define HK_MOVE "PLAY"
|
|
|
|
# define HK_DRAW "DBL HOME"
|
|
|
|
# define HK_REM2CUR "PREV"
|
|
|
|
# define HK_CUR2STACK "DBL PLAY"
|
|
|
|
# define HK_REM2STACK "NEXT"
|
|
|
|
|
2021-02-27 22:07:37 +00:00
|
|
|
#elif CONFIG_KEYPAD == FIIO_M3K_LINUX_PAD
|
2020-10-03 22:17:11 +00:00
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_HOME
|
|
|
|
# define SOL_DOWN BUTTON_OPTION
|
|
|
|
# define SOL_LEFT BUTTON_PREV
|
|
|
|
# define SOL_RIGHT BUTTON_NEXT
|
|
|
|
# define SOL_MOVE_PRE BUTTON_PLAY
|
|
|
|
# define SOL_MOVE (BUTTON_PLAY | BUTTON_REL)
|
|
|
|
# define SOL_DRAW (BUTTON_POWER | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2CUR BUTTON_VOL_DOWN
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_PLAY
|
2018-06-28 10:24:26 +00:00
|
|
|
# define SOL_CUR2STACK (BUTTON_PLAY | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_VOL_UP
|
|
|
|
# define HK_MOVE "PLAY"
|
|
|
|
# define HK_DRAW "DBL HOME"
|
|
|
|
# define HK_REM2CUR "PREV"
|
|
|
|
# define HK_CUR2STACK "DBL PLAY"
|
|
|
|
# define HK_REM2STACK "NEXT"
|
|
|
|
|
2020-10-08 13:47:40 +00:00
|
|
|
#elif CONFIG_KEYPAD == IHIFI_770_PAD || CONFIG_KEYPAD == IHIFI_800_PAD
|
2018-06-29 20:09:28 +00:00
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_PREV
|
|
|
|
# define SOL_DOWN BUTTON_NEXT
|
|
|
|
# define SOL_LEFT BUTTON_HOME
|
|
|
|
# define SOL_RIGHT BUTTON_VOL_DOWN
|
|
|
|
# define SOL_MOVE_PRE BUTTON_VOL_UP
|
|
|
|
# define SOL_MOVE (BUTTON_PLAY | BUTTON_REL)
|
|
|
|
# define SOL_DRAW (BUTTON_POWER | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2CUR (BUTTON_POWER | BUTTON_VOL_DOWN)
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_PLAY
|
|
|
|
# define SOL_CUR2STACK (BUTTON_PLAY | BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK (BUTTON_POWER | BUTTON_VOL_UP)
|
|
|
|
# define HK_MOVE "PLAY"
|
|
|
|
# define HK_DRAW "DBL POWER"
|
|
|
|
# define HK_REM2CUR "POWER"
|
|
|
|
# define HK_CUR2STACK "DBL PLAY"
|
|
|
|
# define HK_REM2STACK "POWER+"
|
|
|
|
|
2020-10-08 13:47:40 +00:00
|
|
|
#elif CONFIG_KEYPAD == EROSQ_PAD
|
2018-06-29 20:09:28 +00:00
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
# define SOL_UP BUTTON_PREV
|
|
|
|
# define SOL_DOWN BUTTON_NEXT
|
2020-10-08 13:47:40 +00:00
|
|
|
# define SOL_LEFT BUTTON_SCROLL_BACK
|
|
|
|
# define SOL_RIGHT BUTTON_SCROLL_FWD
|
|
|
|
# define SOL_MOVE_PRE BUTTON_PLAY
|
2018-06-29 20:09:28 +00:00
|
|
|
# define SOL_MOVE (BUTTON_PLAY | BUTTON_REL)
|
|
|
|
# define SOL_DRAW (BUTTON_POWER | BUTTON_REPEAT)
|
2020-10-08 13:47:40 +00:00
|
|
|
# define SOL_REM2CUR BUTTON_VOL_DOWN
|
2018-06-29 20:09:28 +00:00
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_PLAY
|
|
|
|
# define SOL_CUR2STACK (BUTTON_PLAY | BUTTON_REPEAT)
|
2020-10-08 13:47:40 +00:00
|
|
|
# define SOL_REM2STACK BUTTON_VOL_UP
|
2018-06-29 20:09:28 +00:00
|
|
|
# define HK_MOVE "PLAY"
|
2020-10-08 13:47:40 +00:00
|
|
|
# define HK_DRAW "DBL HOME"
|
|
|
|
# define HK_REM2CUR "PREV"
|
2018-06-29 20:09:28 +00:00
|
|
|
# define HK_CUR2STACK "DBL PLAY"
|
2020-10-08 13:47:40 +00:00
|
|
|
# define HK_REM2STACK "NEXT"
|
2018-06-29 20:09:28 +00:00
|
|
|
|
2021-02-27 22:08:58 +00:00
|
|
|
#elif CONFIG_KEYPAD == FIIO_M3K_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_PRE BUTTON_SELECT
|
|
|
|
# define SOL_MOVE (BUTTON_SELECT|BUTTON_REL)
|
|
|
|
# define SOL_DRAW BUTTON_PLAY
|
|
|
|
# define SOL_REM2CUR BUTTON_VOL_DOWN
|
|
|
|
# define SOL_CUR2STACK_PRE BUTTON_SELECT
|
|
|
|
# define SOL_CUR2STACK (BUTTON_SELECT|BUTTON_REPEAT)
|
|
|
|
# define SOL_REM2STACK BUTTON_VOL_UP
|
|
|
|
# define HK_MOVE "SELECT"
|
|
|
|
# define HK_DRAW "PLAY"
|
|
|
|
# define HK_REM2CUR "VOL-"
|
|
|
|
# define HK_CUR2STACK "HOLD SELECT"
|
|
|
|
# define HK_REM2STACK "VOL+"
|
|
|
|
|
2021-05-23 16:30:58 +00:00
|
|
|
#elif CONFIG_KEYPAD == SHANLING_Q1_PAD
|
|
|
|
# define SOL_QUIT BUTTON_POWER
|
|
|
|
|
2005-10-06 12:42:19 +00:00
|
|
|
#else
|
2008-03-01 22:55:09 +00:00
|
|
|
#error No keymap defined!
|
2005-10-06 12:42:19 +00:00
|
|
|
#endif
|
|
|
|
|
2008-08-23 09:46:38 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
2008-04-27 15:30:19 +00:00
|
|
|
//#ifndef SOL_QUIT
|
|
|
|
//# define SOL_QUIT BUTTON_TOPLEFT
|
|
|
|
//endif
|
|
|
|
#ifndef SOL_UP
|
|
|
|
# define SOL_UP BUTTON_TOPMIDDLE
|
|
|
|
#endif
|
|
|
|
#ifndef SOL_DOWN
|
|
|
|
# define SOL_DOWN BUTTON_BOTTOMMIDDLE
|
|
|
|
#endif
|
|
|
|
#ifndef SOL_LEFT
|
|
|
|
# define SOL_LEFT BUTTON_MIDLEFT
|
|
|
|
#endif
|
|
|
|
#ifndef SOL_RIGHT
|
|
|
|
# define SOL_RIGHT BUTTON_MIDRIGHT
|
|
|
|
#endif
|
|
|
|
#ifndef SOL_MOVE
|
|
|
|
# define SOL_MOVE BUTTON_CENTER
|
|
|
|
# define HK_MOVE "CENTRE"
|
|
|
|
#endif
|
|
|
|
#ifndef SOL_DRAW
|
|
|
|
# define SOL_DRAW BUTTON_TOPLEFT
|
|
|
|
# define HK_DRAW "TOPLEFT"
|
|
|
|
#endif
|
|
|
|
#ifndef SOL_REM2CUR
|
|
|
|
# define SOL_REM2CUR BUTTON_TOPRIGHT
|
|
|
|
# define HK_REM2CUR "TOPRIGHT"
|
|
|
|
#endif
|
|
|
|
#ifndef SOL_CUR2STACK
|
|
|
|
# define SOL_CUR2STACK BUTTON_BOTTOMLEFT
|
|
|
|
# define HK_CUR2STACK "BOTTOMLEFT"
|
|
|
|
#endif
|
|
|
|
#ifndef SOL_REM2STACK
|
|
|
|
# define SOL_REM2STACK BUTTON_BOTTOMRIGHT
|
|
|
|
# define HK_REM2STACK "BOTTOMRIGHT"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
2008-03-22 10:24:28 +00:00
|
|
|
#ifndef HK_LR
|
|
|
|
# define HK_LR "LEFT/RIGHT"
|
|
|
|
#endif
|
2006-09-17 22:14:18 +00:00
|
|
|
#ifndef HK_UD
|
|
|
|
# define HK_UD "UP/DOWN"
|
|
|
|
#endif
|
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/**
|
|
|
|
* Misc constants, graphics and other defines
|
|
|
|
*/
|
2007-03-16 00:52:42 +00:00
|
|
|
|
2008-11-03 14:37:50 +00:00
|
|
|
#include "pluginbitmaps/card_back.h"
|
|
|
|
#include "pluginbitmaps/card_deck.h"
|
|
|
|
#include "pluginbitmaps/solitaire_suitsi.h"
|
2006-02-05 01:58:10 +00:00
|
|
|
|
2007-02-12 04:21:49 +00:00
|
|
|
#define CARD_GFX_WIDTH BMPWIDTH_card_back
|
|
|
|
#define CARD_GFX_HEIGHT BMPHEIGHT_card_back
|
|
|
|
#define CARD_WIDTH (BMPWIDTH_card_back+2)
|
|
|
|
#define CARD_HEIGHT (BMPHEIGHT_card_back+2)
|
2006-09-29 20:39:29 +00:00
|
|
|
|
2009-08-31 13:56:48 +00:00
|
|
|
#if LCD_WIDTH >= 640
|
|
|
|
# define MARGIN 4
|
|
|
|
# define LARGE_CARD
|
|
|
|
# define SYMBOL_HEIGHT 24
|
|
|
|
|
|
|
|
#elif LCD_WIDTH >= 320
|
2006-09-29 20:39:29 +00:00
|
|
|
# define MARGIN 4
|
|
|
|
# define LARGE_CARD
|
|
|
|
# define SYMBOL_HEIGHT 12
|
|
|
|
#elif LCD_WIDTH >= 220
|
|
|
|
# define MARGIN 3
|
|
|
|
# define LARGE_CARD
|
|
|
|
# define SYMBOL_HEIGHT 12
|
|
|
|
#elif LCD_WIDTH >= 160
|
2006-09-03 14:16:03 +00:00
|
|
|
# define MARGIN 2
|
2006-09-29 20:39:29 +00:00
|
|
|
# define SYMBOL_HEIGHT 11
|
|
|
|
#elif LCD_WIDTH >= 128
|
|
|
|
# define MARGIN 1
|
|
|
|
# define SYMBOL_HEIGHT 10
|
2006-08-03 19:57:33 +00:00
|
|
|
#else
|
2006-09-03 14:16:03 +00:00
|
|
|
# define MARGIN 0
|
2006-09-29 20:39:29 +00:00
|
|
|
# define SYMBOL_HEIGHT 8
|
2006-08-03 19:57:33 +00:00
|
|
|
#endif
|
|
|
|
|
2006-09-29 20:39:29 +00:00
|
|
|
#define CARD_START (CARD_HEIGHT+2*MARGIN+1)
|
2005-12-20 22:57:04 +00:00
|
|
|
|
2006-09-29 20:39:29 +00:00
|
|
|
/* background color */
|
2006-08-02 22:17:21 +00:00
|
|
|
#ifdef HAVE_LCD_COLOR
|
2006-09-29 20:39:29 +00:00
|
|
|
# define BACKGROUND_COLOR LCD_RGBPACK(0,157,0)
|
2006-09-30 09:04:05 +00:00
|
|
|
# define FRAME_COLOR LCD_RGBPACK(23,119,218)
|
2006-09-02 22:45:27 +00:00
|
|
|
#elif LCD_DEPTH > 1
|
2006-09-29 20:39:29 +00:00
|
|
|
# define BACKGROUND_COLOR LCD_WHITE
|
2006-09-30 09:04:05 +00:00
|
|
|
# define FRAME_COLOR LCD_BLACK
|
2006-09-02 22:45:27 +00:00
|
|
|
#endif
|
|
|
|
|
2006-09-29 20:39:29 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
#define CONFIG_FILENAME "sol.cfg"
|
2005-12-20 22:57:04 +00:00
|
|
|
|
2006-09-20 23:34:54 +00:00
|
|
|
#define NOT_A_CARD -1
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2005-10-06 12:42:19 +00:00
|
|
|
/* number of cards per suit */
|
|
|
|
#define CARDS_PER_SUIT 13
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2005-10-06 12:42:19 +00:00
|
|
|
/* number of suits */
|
|
|
|
#define SUITS 4
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
#define NUM_CARDS ( CARDS_PER_SUIT * SUITS )
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* number of columns */
|
2004-08-17 06:50:14 +00:00
|
|
|
#define COL_NUM 7
|
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* pseudo column numbers to be used for cursor coordinates */
|
2006-08-02 22:17:21 +00:00
|
|
|
/* columns COL_NUM to COL_NUM + SUITS - 1 correspond to the final stacks */
|
2004-08-21 23:05:36 +00:00
|
|
|
#define STACKS_COL COL_NUM
|
2005-10-06 12:42:19 +00:00
|
|
|
/* column COL_NUM + SUITS corresponds to the remains' stack */
|
|
|
|
#define REM_COL (STACKS_COL + SUITS)
|
2004-08-21 23:05:36 +00:00
|
|
|
|
2006-09-20 23:34:54 +00:00
|
|
|
#define NOT_A_COL -1
|
2004-08-21 23:05:36 +00:00
|
|
|
|
2011-05-22 13:53:31 +00:00
|
|
|
#if defined(SOL_LEFT_PRE) || defined(SOL_RIGHT_PRE) || \
|
|
|
|
defined(SOL_DOWN_PRE) || defined(SOL_UP_PRE) || \
|
|
|
|
defined(SOL_CUR2STACK_PRE) || defined(SOL_MOVE_PRE) || \
|
|
|
|
defined(SOL_REM2CUR_PRE) || defined(SOL_REM2STACK_PRE) || \
|
|
|
|
defined(SOL_DRAW_PRE)
|
|
|
|
# define NEED_LASTBUTTON_VAR
|
|
|
|
#endif
|
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
typedef struct
|
|
|
|
{
|
2006-09-20 23:34:54 +00:00
|
|
|
signed char suit;
|
|
|
|
signed char num;
|
|
|
|
bool known : 1;
|
|
|
|
bool used : 1; /* this is what is used when dealing cards */
|
|
|
|
signed char next;
|
2006-08-02 22:17:21 +00:00
|
|
|
} card_t;
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/**
|
|
|
|
* LCD card drawing routines
|
|
|
|
*/
|
|
|
|
|
|
|
|
static void draw_cursor( int x, int y )
|
|
|
|
{
|
|
|
|
rb->lcd_set_drawmode( DRMODE_COMPLEMENT );
|
2006-09-29 20:39:29 +00:00
|
|
|
rb->lcd_fillrect( x+1, y+1, CARD_GFX_WIDTH, CARD_GFX_HEIGHT );
|
|
|
|
#ifdef LARGE_CARD
|
|
|
|
rb->lcd_drawpixel( x+1, y+1 );
|
|
|
|
rb->lcd_drawpixel( x+1, y+CARD_HEIGHT-2 );
|
|
|
|
rb->lcd_drawpixel( x+CARD_WIDTH-2, y+1 );
|
|
|
|
rb->lcd_drawpixel( x+CARD_WIDTH-2, y+CARD_HEIGHT-2 );
|
|
|
|
#endif
|
2006-08-02 22:17:21 +00:00
|
|
|
rb->lcd_set_drawmode( DRMODE_SOLID );
|
|
|
|
}
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/* Draw a card's border, select it if it's selected and draw the cursor
|
2006-09-20 23:34:54 +00:00
|
|
|
* if the cursor is currently over the card */
|
2006-08-02 22:17:21 +00:00
|
|
|
static void draw_card_ext( int x, int y, bool selected, bool cursor )
|
|
|
|
{
|
2006-11-19 22:49:37 +00:00
|
|
|
#if LCD_DEPTH > 1
|
|
|
|
int oldfg = rb->lcd_get_foreground();
|
|
|
|
|
|
|
|
rb->lcd_set_foreground( LCD_BLACK );
|
|
|
|
#endif
|
2006-09-29 20:39:29 +00:00
|
|
|
#ifdef LARGE_CARD
|
|
|
|
rb->lcd_hline( x+2, x+CARD_WIDTH-3, y );
|
|
|
|
rb->lcd_hline( x+2, x+CARD_WIDTH-3, y+CARD_HEIGHT-1 );
|
|
|
|
rb->lcd_vline( x, y+2, y+CARD_HEIGHT-3 );
|
|
|
|
rb->lcd_vline( x+CARD_WIDTH-1, y+2, y+CARD_HEIGHT-3 );
|
|
|
|
rb->lcd_drawpixel( x+1, y+1 );
|
|
|
|
rb->lcd_drawpixel( x+1, y+CARD_HEIGHT-2 );
|
|
|
|
rb->lcd_drawpixel( x+CARD_WIDTH-2, y+1 );
|
|
|
|
rb->lcd_drawpixel( x+CARD_WIDTH-2, y+CARD_HEIGHT-2 );
|
|
|
|
#else
|
2006-09-06 01:33:26 +00:00
|
|
|
rb->lcd_hline( x+1, x+CARD_WIDTH-2, y );
|
|
|
|
rb->lcd_hline( x+1, x+CARD_WIDTH-2, y+CARD_HEIGHT-1 );
|
|
|
|
rb->lcd_vline( x, y+1, y+CARD_HEIGHT-2 );
|
|
|
|
rb->lcd_vline( x+CARD_WIDTH-1, y+1, y+CARD_HEIGHT-2 );
|
2006-09-29 20:39:29 +00:00
|
|
|
#endif
|
2006-08-02 22:17:21 +00:00
|
|
|
|
|
|
|
if( selected )
|
|
|
|
{
|
2006-11-19 22:49:37 +00:00
|
|
|
#if LCD_DEPTH > 1
|
|
|
|
rb->lcd_set_foreground( FRAME_COLOR );
|
|
|
|
#endif
|
2006-09-06 01:33:26 +00:00
|
|
|
rb->lcd_drawrect( x+1, y+1, CARD_WIDTH-2, CARD_HEIGHT-2 );
|
2006-09-29 20:39:29 +00:00
|
|
|
#ifdef LARGE_CARD
|
|
|
|
rb->lcd_drawrect( x+2, y+2, CARD_WIDTH-4, CARD_HEIGHT-4 );
|
|
|
|
#endif
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-11-19 22:49:37 +00:00
|
|
|
#if LCD_DEPTH > 1
|
|
|
|
rb->lcd_set_foreground( oldfg );
|
|
|
|
#endif
|
2006-09-30 09:04:05 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cursor )
|
|
|
|
{
|
|
|
|
draw_cursor( x, y );
|
|
|
|
}
|
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/* Draw a card's inner graphics */
|
2006-09-20 23:34:54 +00:00
|
|
|
static void draw_card( card_t *card, int x, int y,
|
2006-09-29 20:39:29 +00:00
|
|
|
bool selected, bool cursor )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2006-09-20 23:34:54 +00:00
|
|
|
if( card->known )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2007-02-12 04:21:49 +00:00
|
|
|
rb->lcd_bitmap_part( card_deck, CARD_GFX_WIDTH * card->num,
|
2020-10-08 13:47:40 +00:00
|
|
|
CARD_GFX_HEIGHT * card->suit,
|
|
|
|
STRIDE(SCREEN_MAIN,
|
2009-09-04 00:46:24 +00:00
|
|
|
BMPWIDTH_card_deck, BMPHEIGHT_card_deck),
|
2006-09-29 20:39:29 +00:00
|
|
|
x+1, y+1, CARD_GFX_WIDTH, CARD_GFX_HEIGHT );
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2007-02-12 04:21:49 +00:00
|
|
|
rb->lcd_bitmap( card_back, x+1, y+1,
|
2006-09-29 20:39:29 +00:00
|
|
|
CARD_GFX_WIDTH, CARD_GFX_HEIGHT );
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
draw_card_ext( x, y, selected, cursor );
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Draw an empty stack */
|
|
|
|
static void draw_empty_stack( int s, int x, int y, bool cursor )
|
|
|
|
{
|
2006-09-29 20:39:29 +00:00
|
|
|
rb->lcd_bitmap_part( solitaire_suitsi, 0,
|
2020-10-08 13:47:40 +00:00
|
|
|
CARD_GFX_HEIGHT * s,
|
2009-09-04 00:46:24 +00:00
|
|
|
STRIDE( SCREEN_MAIN,
|
|
|
|
BMPWIDTH_solitaire_suitsi, BMPHEIGHT_solitaire_suitsi),
|
2009-08-31 13:56:48 +00:00
|
|
|
x+1, y+1, CARD_GFX_WIDTH, CARD_GFX_HEIGHT );
|
2006-08-02 22:17:21 +00:00
|
|
|
|
|
|
|
draw_card_ext( x, y, false, cursor );
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
|
2009-07-14 13:03:17 +00:00
|
|
|
/* Help */
|
|
|
|
static bool solitaire_help( void )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2009-07-14 13:03:17 +00:00
|
|
|
static char* help_text[] = {
|
2009-07-27 16:55:37 +00:00
|
|
|
"Solitaire", "", "Controls", "",
|
2009-07-14 13:03:17 +00:00
|
|
|
HK_LR ":", "Move", "the", "cursor", "to", "the",
|
|
|
|
"previous/", "next", "column.", "",
|
|
|
|
HK_UD ":", "Move", "the", "cursor", "up/", "down", "in", "the",
|
|
|
|
"column.", "",
|
|
|
|
HK_MOVE ":", "Select", "cards,", "move", "cards...", "",
|
|
|
|
HK_DRAW ":", "Deselect", "a", "card", "if", "it", "was", "selected.",
|
|
|
|
"Else", "draw", "new", "card(s)", "from", "the", "remains",
|
|
|
|
"stack.", "", "",
|
|
|
|
"Shortcuts", "",
|
|
|
|
HK_REM2CUR ":", "Put", "the", "card", "on", "top", "of", "the",
|
|
|
|
"remains", "stack", "on", "top", "of", "the", "cursor.", "",
|
|
|
|
HK_CUR2STACK ":", "Put", "the", "card", "under", "the", "cursor",
|
|
|
|
"on", "one", "of", "the", "4", "final", "stacks.", "",
|
|
|
|
HK_REM2STACK ":", "Put", "the", "card", "on", "top", "of", "the",
|
|
|
|
"remains", "stack", "on", "one", "of", "the", "4", "final",
|
|
|
|
"stacks."
|
|
|
|
};
|
2009-07-27 16:55:37 +00:00
|
|
|
static struct style_text formation[]={
|
|
|
|
{ 0, TEXT_CENTER|TEXT_UNDERLINE },
|
|
|
|
{ 2, C_RED },
|
|
|
|
{ 48, C_RED },
|
2010-02-22 07:17:15 +00:00
|
|
|
LAST_STYLE_ITEM
|
2009-07-27 16:55:37 +00:00
|
|
|
};
|
2010-02-22 07:17:15 +00:00
|
|
|
if (display_text(ARRAYLEN(help_text), help_text, formation, NULL, true))
|
2009-07-14 13:03:17 +00:00
|
|
|
return true;
|
|
|
|
return false;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Custom menu / options
|
|
|
|
*/
|
2007-03-16 00:52:42 +00:00
|
|
|
|
2005-12-20 22:57:04 +00:00
|
|
|
#define CFGFILE_VERSION 0
|
2006-09-15 06:24:36 +00:00
|
|
|
|
2006-10-23 22:44:46 +00:00
|
|
|
struct sol_config {
|
|
|
|
int draw_type;
|
|
|
|
};
|
|
|
|
|
2008-05-16 20:03:27 +00:00
|
|
|
struct sol_config sol_disk = {0};
|
2006-10-23 22:44:46 +00:00
|
|
|
struct sol_config sol;
|
2005-12-20 22:57:04 +00:00
|
|
|
|
|
|
|
static struct configdata config[] = {
|
2009-01-17 22:53:12 +00:00
|
|
|
{ TYPE_INT, 0, 1, { .int_p = &sol_disk.draw_type }, "draw_type", NULL }
|
2005-12-20 22:57:04 +00:00
|
|
|
};
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2009-06-16 04:25:21 +00:00
|
|
|
static const struct opt_items drawcards[2] = {
|
|
|
|
{ "Draw Three Cards", -1 },
|
|
|
|
{ "Draw One Card", -1 },
|
|
|
|
};
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-09-18 00:36:09 +00:00
|
|
|
void solitaire_init(void);
|
2005-12-20 22:57:04 +00:00
|
|
|
|
2006-09-18 00:36:09 +00:00
|
|
|
/* menu return codes */
|
2007-09-30 16:39:36 +00:00
|
|
|
enum { MENU_RESUME, MENU_SAVE_AND_QUIT, MENU_QUIT, MENU_USB };
|
2006-09-18 00:36:09 +00:00
|
|
|
|
2009-06-26 17:59:33 +00:00
|
|
|
static bool _ingame;
|
2020-07-19 17:42:04 +00:00
|
|
|
static int solitaire_menu_cb(int action,
|
|
|
|
const struct menu_item_ex *this_item,
|
|
|
|
struct gui_synclist *this_list)
|
2009-06-26 17:59:33 +00:00
|
|
|
{
|
2020-07-19 17:42:04 +00:00
|
|
|
(void)this_list;
|
2009-06-26 17:59:33 +00:00
|
|
|
int i = (intptr_t)this_item;
|
|
|
|
if( action == ACTION_REQUEST_MENUITEM )
|
|
|
|
{
|
|
|
|
if((!_ingame && (i==0 || i==5)) || ( _ingame && i==2 ))
|
|
|
|
return ACTION_EXIT_MENUITEM;
|
|
|
|
}
|
|
|
|
return action;
|
|
|
|
}
|
|
|
|
|
2011-09-17 17:20:27 +00:00
|
|
|
static int solitaire_menu(bool in_game)
|
2006-09-18 00:36:09 +00:00
|
|
|
{
|
2009-06-16 04:25:21 +00:00
|
|
|
int selected = 0;
|
2006-09-18 00:36:09 +00:00
|
|
|
int result = -1;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2009-06-26 17:59:33 +00:00
|
|
|
MENUITEM_STRINGLIST(menu, "Solitaire Menu", solitaire_menu_cb,
|
|
|
|
"Resume Game", "Start New Game",
|
|
|
|
"Draw Cards Option",
|
|
|
|
"Help", "Playback Control",
|
2019-11-04 02:44:48 +00:00
|
|
|
"Quit without Saving", "Quit");
|
2009-06-26 17:59:33 +00:00
|
|
|
_ingame = in_game;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-09-18 00:36:09 +00:00
|
|
|
while (result < 0)
|
|
|
|
{
|
2009-06-26 17:59:33 +00:00
|
|
|
switch (rb->do_menu(&menu, &selected, NULL, false))
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2009-06-16 04:25:21 +00:00
|
|
|
default:
|
2006-09-18 00:36:09 +00:00
|
|
|
result = MENU_RESUME;
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
|
|
|
|
2006-09-18 00:36:09 +00:00
|
|
|
case MENU_ATTACHED_USB:
|
|
|
|
result = MENU_USB;
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
|
|
|
|
2006-09-18 00:36:09 +00:00
|
|
|
case 0:
|
|
|
|
result = MENU_RESUME;
|
|
|
|
break;
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2006-09-18 00:36:09 +00:00
|
|
|
case 1:
|
2009-06-26 17:59:33 +00:00
|
|
|
solitaire_init();
|
|
|
|
result = MENU_RESUME;
|
2004-08-21 23:05:36 +00:00
|
|
|
break;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-09-18 00:36:09 +00:00
|
|
|
case 2:
|
2009-06-26 17:59:33 +00:00
|
|
|
if (rb->set_option("Draw Cards Option", &sol.draw_type,
|
|
|
|
INT, drawcards, 2, NULL))
|
2006-09-18 00:36:09 +00:00
|
|
|
result = MENU_USB;
|
|
|
|
break;
|
2006-07-11 21:38:27 +00:00
|
|
|
|
2008-05-16 20:03:27 +00:00
|
|
|
case 3:
|
2009-07-14 13:03:17 +00:00
|
|
|
if (solitaire_help())
|
2009-06-26 17:59:33 +00:00
|
|
|
result = MENU_USB;
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 4:
|
2009-01-16 10:34:40 +00:00
|
|
|
playback_control(NULL);
|
2007-03-16 00:52:42 +00:00
|
|
|
break;
|
|
|
|
|
2009-06-26 17:59:33 +00:00
|
|
|
case 5:
|
2019-11-04 02:44:48 +00:00
|
|
|
result = MENU_QUIT;
|
2007-09-30 16:39:36 +00:00
|
|
|
break;
|
|
|
|
|
2009-06-26 17:59:33 +00:00
|
|
|
case 6:
|
2019-11-04 02:44:48 +00:00
|
|
|
result = MENU_SAVE_AND_QUIT;
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2006-09-18 00:36:09 +00:00
|
|
|
return result;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/**
|
|
|
|
* Global variables
|
|
|
|
*/
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* player's cursor */
|
2006-09-20 23:34:54 +00:00
|
|
|
int cur_card;
|
2004-08-18 12:06:10 +00:00
|
|
|
/* player's cursor column num */
|
2006-09-20 23:34:54 +00:00
|
|
|
int cur_col;
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* selected card */
|
2006-09-20 23:34:54 +00:00
|
|
|
int sel_card;
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* the deck */
|
2006-08-02 22:17:21 +00:00
|
|
|
card_t deck[ NUM_CARDS ];
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* the remaining cards */
|
2006-09-04 19:36:09 +00:00
|
|
|
/* first card of the remains' stack */
|
2006-09-20 23:34:54 +00:00
|
|
|
int rem;
|
2006-09-04 19:36:09 +00:00
|
|
|
/* upper visible card from the remains' stack */
|
2006-09-20 23:34:54 +00:00
|
|
|
int cur_rem;
|
2006-09-04 19:36:09 +00:00
|
|
|
/* number of cards drawn from the remains stack - 1 */
|
2006-09-20 23:34:54 +00:00
|
|
|
int count_rem;
|
2006-09-04 19:36:09 +00:00
|
|
|
/* number of cards per draw of the remains' stack */
|
2006-09-20 23:34:54 +00:00
|
|
|
int cards_per_draw;
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* the 7 game columns */
|
2006-09-20 23:34:54 +00:00
|
|
|
int cols[COL_NUM];
|
2005-10-06 12:42:19 +00:00
|
|
|
/* the 4 final stacks */
|
2006-09-20 23:34:54 +00:00
|
|
|
int stacks[SUITS];
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/**
|
|
|
|
* Card handling routines
|
|
|
|
*/
|
|
|
|
|
2011-09-17 17:20:27 +00:00
|
|
|
static int next_random_card( card_t *deck )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2006-09-20 23:34:54 +00:00
|
|
|
int i,r;
|
2006-08-02 22:17:21 +00:00
|
|
|
|
|
|
|
r = rb->rand()%(NUM_CARDS)+1;
|
|
|
|
i = 0;
|
|
|
|
|
|
|
|
while( r>0 )
|
|
|
|
{
|
|
|
|
i = (i + 1)%(NUM_CARDS);
|
|
|
|
if( !deck[i].used ) r--;
|
|
|
|
}
|
|
|
|
|
2006-09-20 23:34:54 +00:00
|
|
|
deck[i].used = true;
|
2006-08-02 22:17:21 +00:00
|
|
|
|
|
|
|
return i;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* initialize the game */
|
2006-08-02 22:17:21 +00:00
|
|
|
void solitaire_init( void )
|
|
|
|
{
|
2005-12-20 22:57:04 +00:00
|
|
|
|
2006-09-20 23:34:54 +00:00
|
|
|
int c;
|
2006-08-02 22:17:21 +00:00
|
|
|
int i, j;
|
|
|
|
|
|
|
|
/* number of cards that are drawn on the remains' stack (by pressing F2) */
|
2006-10-23 22:44:46 +00:00
|
|
|
if( sol.draw_type == 0 )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2006-09-29 20:39:29 +00:00
|
|
|
cards_per_draw = 3;
|
2005-12-20 22:57:04 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
else
|
|
|
|
{
|
2006-09-29 20:39:29 +00:00
|
|
|
cards_per_draw = 1;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* init deck */
|
2006-08-02 22:17:21 +00:00
|
|
|
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;
|
2006-09-20 23:34:54 +00:00
|
|
|
card.known = true;
|
|
|
|
card.used = false;
|
2006-08-02 22:17:21 +00:00
|
|
|
card.next = NOT_A_CARD;
|
|
|
|
#undef card
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* deal the cards ... */
|
|
|
|
/* ... in the columns */
|
2006-08-02 22:17:21 +00:00
|
|
|
for( i=0; i<COL_NUM; i++ )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
c = NOT_A_CARD;
|
2006-08-02 22:17:21 +00:00
|
|
|
for( j=0; j<=i; j++ )
|
|
|
|
{
|
|
|
|
if( c == NOT_A_CARD )
|
|
|
|
{
|
|
|
|
cols[i] = next_random_card( deck );
|
2004-08-17 06:50:14 +00:00
|
|
|
c = cols[i];
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
deck[c].next = next_random_card( deck );
|
2004-08-17 06:50:14 +00:00
|
|
|
c = deck[c].next;
|
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
if( j < i )
|
2006-09-20 23:34:54 +00:00
|
|
|
deck[c].known = false;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* ... shuffle what's left of the deck */
|
2004-08-17 06:50:14 +00:00
|
|
|
rem = next_random_card(deck);
|
|
|
|
c = rem;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
for( i=1; i < NUM_CARDS - COL_NUM * (COL_NUM + 1)/2; i++ )
|
|
|
|
{
|
|
|
|
deck[c].next = next_random_card( deck );
|
2004-08-17 06:50:14 +00:00
|
|
|
c = deck[c].next;
|
|
|
|
}
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* we now finished dealing the cards. The game can start ! (at last) */
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* init the stack */
|
2006-08-02 22:17:21 +00:00
|
|
|
for( i = 0; i<SUITS; i++ )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
stacks[i] = NOT_A_CARD;
|
|
|
|
}
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* the cursor starts on upper left card */
|
2004-08-17 06:50:14 +00:00
|
|
|
cur_card = cols[0];
|
|
|
|
cur_col = 0;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* no card is selected */
|
2004-08-17 06:50:14 +00:00
|
|
|
sel_card = NOT_A_CARD;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* init the remainder */
|
2004-08-17 06:50:14 +00:00
|
|
|
cur_rem = NOT_A_CARD;
|
2006-07-11 21:38:27 +00:00
|
|
|
|
2006-09-29 20:39:29 +00:00
|
|
|
count_rem = -1;
|
2005-06-26 19:35:29 +00:00
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* find the column number in which 'card' can be found */
|
2011-09-17 17:20:27 +00:00
|
|
|
static int find_card_col( int card )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
int i;
|
2006-09-20 23:34:54 +00:00
|
|
|
int c;
|
2004-08-21 23:05:36 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
if( card == NOT_A_CARD ) return NOT_A_COL;
|
2004-08-21 23:05:36 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
for( i=0; i<COL_NUM; i++ )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
c = cols[i];
|
2006-08-02 22:17:21 +00:00
|
|
|
while( c != NOT_A_CARD )
|
|
|
|
{
|
|
|
|
if( c == card ) return i;
|
2004-08-21 23:05:36 +00:00
|
|
|
c = deck[c].next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
for( i=0; i<SUITS; i++ )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
c = stacks[i];
|
2006-08-02 22:17:21 +00:00
|
|
|
while( c != NOT_A_CARD )
|
|
|
|
{
|
|
|
|
if( c == card ) return STACKS_COL + i;
|
2004-08-21 23:05:36 +00:00
|
|
|
c = deck[c].next;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return REM_COL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* find the card preceding 'card' */
|
|
|
|
/* if it doesn't exist, return NOT_A_CARD */
|
2011-09-17 17:20:27 +00:00
|
|
|
static int find_prev_card( int card ){
|
2004-08-21 23:05:36 +00:00
|
|
|
int i;
|
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
for( i=0; i < NUM_CARDS; i++ )
|
|
|
|
{
|
|
|
|
if( deck[i].next == card ) return i;
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return NOT_A_CARD;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* find the last card of a given column */
|
2011-09-17 17:20:27 +00:00
|
|
|
static int find_last_card( int col )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2006-09-20 23:34:54 +00:00
|
|
|
int c;
|
2004-08-21 23:05:36 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
if( col < COL_NUM )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
c = cols[col];
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else if( col < REM_COL )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
c = stacks[col - STACKS_COL];
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2006-09-03 16:54:42 +00:00
|
|
|
c = cur_rem;
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if(c == NOT_A_CARD)
|
|
|
|
return c;
|
2006-08-02 22:17:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
while(deck[c].next != NOT_A_CARD)
|
2004-08-21 23:05:36 +00:00
|
|
|
c = deck[c].next;
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
enum move { MOVE_OK, MOVE_NOT_OK };
|
|
|
|
|
2011-09-17 17:20:27 +00:00
|
|
|
static enum move move_card( int dest_col, int src_card )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
/* the column on which to take src_card */
|
2006-09-20 23:34:54 +00:00
|
|
|
int src_col;
|
2004-08-21 23:05:36 +00:00
|
|
|
|
|
|
|
/* the last card of dest_col */
|
2006-09-20 23:34:54 +00:00
|
|
|
int dest_card;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* the card under src_card */
|
2006-09-20 23:34:54 +00:00
|
|
|
int src_card_prev;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* you can't move no card (at least, it doesn't have any consequence) */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( src_card == NOT_A_CARD ) return MOVE_NOT_OK;
|
2004-08-21 23:05:36 +00:00
|
|
|
/* you can't put a card back on the remains' stack */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( dest_col == REM_COL ) return MOVE_NOT_OK;
|
2006-09-04 21:33:08 +00:00
|
|
|
/* you can't move an unknown card */
|
|
|
|
if( !deck[src_card].known ) return MOVE_NOT_OK;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
src_col = find_card_col( src_card );
|
|
|
|
dest_card = find_last_card( dest_col );
|
|
|
|
src_card_prev = find_prev_card( src_card );
|
2004-08-21 23:05:36 +00:00
|
|
|
|
2005-10-06 12:42:19 +00:00
|
|
|
/* you can't move more than one card at a time from the final stack */
|
2004-08-21 23:05:36 +00:00
|
|
|
/* to the rest of the game */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( src_col >= COL_NUM && src_col < REM_COL
|
|
|
|
&& deck[src_card].next != NOT_A_CARD )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
return MOVE_NOT_OK;
|
|
|
|
}
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* if we (that means dest) are on one of the 7 columns ... */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( dest_col < COL_NUM )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
/* ... check is we are on an empty color and that the src is a king */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( dest_card == NOT_A_CARD
|
|
|
|
&& deck[src_card].num == CARDS_PER_SUIT - 1 )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
/* this is a winning combination */
|
|
|
|
cols[dest_col] = src_card;
|
|
|
|
}
|
2006-09-10 20:04:17 +00:00
|
|
|
/* ... or check if the cards follow one another and have
|
|
|
|
* different colorsuit */
|
2006-08-02 22:17:21 +00:00
|
|
|
else if(( deck[dest_card].suit + deck[src_card].suit)%2==1
|
|
|
|
&& deck[dest_card].num == deck[src_card].num + 1 )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
/* this is a winning combination */
|
|
|
|
deck[dest_card].next = src_card;
|
|
|
|
}
|
|
|
|
/* ... or, humpf, well that's not good news */
|
2006-08-02 22:17:21 +00:00
|
|
|
else
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
/* this is not a winning combination */
|
|
|
|
return MOVE_NOT_OK;
|
|
|
|
}
|
|
|
|
}
|
2005-10-06 12:42:19 +00:00
|
|
|
/* if we are on one of the 4 final stacks ... */
|
2006-08-02 22:17:21 +00:00
|
|
|
else if( dest_col < REM_COL )
|
2006-10-01 20:55:41 +00:00
|
|
|
{
|
|
|
|
/* ... check if we are on an empty stack... */
|
|
|
|
if( dest_card == NOT_A_CARD )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2006-10-01 20:55:41 +00:00
|
|
|
/* ... and the src is an ace and this is the correct final stack */
|
|
|
|
if( 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;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* this is not a winning combination */
|
|
|
|
return MOVE_NOT_OK;
|
|
|
|
}
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
2006-10-01 20:55:41 +00:00
|
|
|
else /* non-empty stack */
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2006-10-01 20:55:41 +00:00
|
|
|
/* ...check if the cards follow one another, have the same suit and
|
|
|
|
* {that src has no .next element or is from the remains' stack} */
|
|
|
|
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
|
|
|
|
{
|
|
|
|
/* this is not a winning combination */
|
|
|
|
return MOVE_NOT_OK;
|
|
|
|
}
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
/* if we are on the remains' stack */
|
2006-08-02 22:17:21 +00:00
|
|
|
else
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
/* you can't move a card back to the remains' stack */
|
|
|
|
return MOVE_NOT_OK;
|
|
|
|
}
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* if the src card is from the remains' stack, we don't want to take
|
|
|
|
* the following cards */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( src_col == REM_COL )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
/* if src card is the first card from the stack */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( src_card_prev == NOT_A_CARD )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
rem = deck[src_card].next;
|
|
|
|
}
|
|
|
|
/* if src card is not the first card from the stack */
|
2006-08-02 22:17:21 +00:00
|
|
|
else
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
deck[src_card_prev].next = deck[src_card].next;
|
|
|
|
}
|
|
|
|
deck[src_card].next = NOT_A_CARD;
|
2006-07-11 21:38:27 +00:00
|
|
|
cur_rem = src_card_prev;
|
2006-09-04 19:36:09 +00:00
|
|
|
count_rem--;
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
|
|
|
/* if the src card is from somewhere else, just take everything */
|
2006-08-02 22:17:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
if( src_card_prev == NOT_A_CARD )
|
|
|
|
{
|
|
|
|
if( src_col < COL_NUM )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cols[src_col] = NOT_A_CARD;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
stacks[src_col - STACKS_COL] = NOT_A_CARD;
|
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
deck[src_card_prev].next = NOT_A_CARD;
|
2008-05-16 20:03:27 +00:00
|
|
|
deck[src_card_prev].known = true;
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
|
|
|
}
|
2005-12-20 22:57:04 +00:00
|
|
|
sel_card = NOT_A_CARD;
|
2004-08-21 23:05:36 +00:00
|
|
|
/* tada ! */
|
|
|
|
return MOVE_OK;
|
|
|
|
}
|
|
|
|
|
2007-09-30 16:39:36 +00:00
|
|
|
enum { SOLITAIRE_WIN, SOLITAIRE_SAVE_AND_QUIT, SOLITAIRE_QUIT, SOLITAIRE_USB };
|
2006-09-04 21:33:08 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/**
|
2006-09-04 21:33:08 +00:00
|
|
|
* Bouncing cards at the end of the game
|
2006-08-02 22:17:21 +00:00
|
|
|
*/
|
2007-03-16 00:52:42 +00:00
|
|
|
|
2006-09-21 20:12:04 +00:00
|
|
|
#define BC_ACCEL ((1<<16)*LCD_HEIGHT/128)
|
|
|
|
#define BC_MYSPEED (6*BC_ACCEL)
|
2006-09-22 22:44:57 +00:00
|
|
|
#define BC_MXSPEED (6*LCD_HEIGHT/128)
|
2006-09-21 20:12:04 +00:00
|
|
|
|
2011-09-17 17:20:27 +00:00
|
|
|
static int bouncing_cards( void )
|
2006-09-04 21:33:08 +00:00
|
|
|
{
|
2006-09-15 06:24:36 +00:00
|
|
|
int i, j, x, vx, y, fp_y, fp_vy, button;
|
2005-12-20 22:57:04 +00:00
|
|
|
|
2006-09-04 21:33:08 +00:00
|
|
|
/* flush the button queue */
|
|
|
|
while( ( button = rb->button_get( false ) ) != BUTTON_NONE )
|
|
|
|
{
|
|
|
|
if( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
|
|
|
|
return SOLITAIRE_USB;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* fun stuff :) */
|
|
|
|
for( i = CARDS_PER_SUIT-1; i>=0; i-- )
|
|
|
|
{
|
|
|
|
for( j = 0; j < SUITS; j++ )
|
|
|
|
{
|
2006-09-06 01:33:26 +00:00
|
|
|
x = LCD_WIDTH-(CARD_WIDTH*4+4+MARGIN)+CARD_WIDTH*j+j+1;
|
2006-09-21 20:12:04 +00:00
|
|
|
fp_y = MARGIN<<16;
|
2006-09-04 21:33:08 +00:00
|
|
|
|
2006-09-22 22:44:57 +00:00
|
|
|
#if LCD_WIDTH > 200
|
|
|
|
vx = rb->rand() % (4*BC_MXSPEED/3-2) - BC_MXSPEED;
|
|
|
|
if( vx >= -1 )
|
|
|
|
vx += 3;
|
|
|
|
#else
|
2006-09-21 20:12:04 +00:00
|
|
|
vx = rb->rand() % (4*BC_MXSPEED/3) - BC_MXSPEED;
|
|
|
|
if( vx >= 0 )
|
|
|
|
vx++;
|
2006-09-22 22:44:57 +00:00
|
|
|
#endif
|
2006-09-04 21:33:08 +00:00
|
|
|
|
2006-09-21 20:12:04 +00:00
|
|
|
fp_vy = -rb->rand() % BC_MYSPEED;
|
2006-09-04 21:33:08 +00:00
|
|
|
|
|
|
|
while( x < LCD_WIDTH && x + CARD_WIDTH > 0 )
|
|
|
|
{
|
2006-09-21 20:12:04 +00:00
|
|
|
fp_vy += BC_ACCEL;
|
2006-09-04 21:33:08 +00:00
|
|
|
x += vx;
|
2006-09-15 06:24:36 +00:00
|
|
|
fp_y += fp_vy;
|
2006-09-21 20:12:04 +00:00
|
|
|
if( fp_y >= (LCD_HEIGHT-CARD_HEIGHT) << 16 )
|
2006-09-04 21:33:08 +00:00
|
|
|
{
|
2006-09-21 20:12:04 +00:00
|
|
|
fp_vy = -fp_vy*4/5;
|
|
|
|
fp_y = (LCD_HEIGHT-CARD_HEIGHT) << 16;
|
2006-09-04 21:33:08 +00:00
|
|
|
}
|
2006-09-21 20:12:04 +00:00
|
|
|
y = fp_y >> 16;
|
2006-09-20 23:34:54 +00:00
|
|
|
draw_card( &deck[j*CARDS_PER_SUIT+i], x, y,
|
2006-09-29 20:39:29 +00:00
|
|
|
false, false );
|
2006-09-05 20:54:46 +00:00
|
|
|
rb->lcd_update_rect( x<0?0:x, y<0?0:y,
|
2006-09-06 01:33:26 +00:00
|
|
|
CARD_WIDTH, CARD_HEIGHT );
|
2006-09-04 21:33:08 +00:00
|
|
|
|
2006-09-06 01:33:26 +00:00
|
|
|
button = rb->button_get_w_tmo( 2 );
|
2006-09-04 21:33:08 +00:00
|
|
|
if( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
|
|
|
|
return SOLITAIRE_USB;
|
|
|
|
if( button == SOL_QUIT || button == SOL_MOVE )
|
|
|
|
return SOLITAIRE_WIN;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return SOLITAIRE_WIN;
|
|
|
|
}
|
|
|
|
|
2007-09-24 22:19:59 +00:00
|
|
|
/**
|
|
|
|
* Game save/load routines
|
|
|
|
*/
|
2011-09-17 17:20:27 +00:00
|
|
|
static void get_save_filename( char *buf )
|
2007-09-24 22:19:59 +00:00
|
|
|
{
|
2011-03-02 23:43:54 +00:00
|
|
|
#ifdef APPLICATION
|
|
|
|
rb->snprintf(buf, sizeof(buf), PLUGIN_DATA_DIR "/sol.save");
|
|
|
|
#else
|
2007-09-24 22:19:59 +00:00
|
|
|
char *s;
|
|
|
|
rb->strcpy( buf, rb->plugin_get_current_filename() );
|
|
|
|
s = rb->strrchr( buf, '/' ) + 1;
|
|
|
|
*s = '\0';
|
|
|
|
rb->strcat( s, "sol.save" );
|
2011-03-02 23:43:54 +00:00
|
|
|
#endif
|
2007-09-24 22:19:59 +00:00
|
|
|
}
|
|
|
|
|
2011-09-17 17:20:27 +00:00
|
|
|
static int open_save_file( int flags )
|
2007-09-24 22:19:59 +00:00
|
|
|
{
|
|
|
|
char buf[MAX_PATH];
|
|
|
|
get_save_filename( buf );
|
2010-05-06 17:35:13 +00:00
|
|
|
return rb->open( buf, flags, 0666);
|
2007-09-24 22:19:59 +00:00
|
|
|
}
|
|
|
|
|
2011-09-17 17:20:27 +00:00
|
|
|
static void delete_save_file( void )
|
2007-09-24 22:19:59 +00:00
|
|
|
{
|
|
|
|
char buf[MAX_PATH];
|
2007-09-30 16:39:36 +00:00
|
|
|
get_save_filename( buf );
|
2007-09-24 22:19:59 +00:00
|
|
|
rb->remove( buf );
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef write
|
|
|
|
# undef write
|
|
|
|
#endif
|
2011-09-17 17:20:27 +00:00
|
|
|
static int save_write( int fd, const void *buf, size_t count, int *checksum )
|
2007-09-24 22:19:59 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
2009-01-07 09:53:46 +00:00
|
|
|
if( rb->write( fd, buf, count ) < (ssize_t)count )
|
2007-09-24 22:19:59 +00:00
|
|
|
return 1;
|
|
|
|
for( i = 0; i < count; i++ )
|
|
|
|
*checksum += (int)(((const char *)buf)[i]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifdef read
|
|
|
|
# undef read
|
|
|
|
#endif
|
2011-09-17 17:20:27 +00:00
|
|
|
static int save_read( int fd, void *buf, size_t count, int *checksum )
|
2007-09-24 22:19:59 +00:00
|
|
|
{
|
|
|
|
size_t i;
|
2009-01-07 09:53:46 +00:00
|
|
|
if( rb->read( fd, buf, count ) < (ssize_t)count )
|
2007-09-24 22:19:59 +00:00
|
|
|
return 1;
|
|
|
|
for( i = 0; i < count; i++ )
|
|
|
|
*checksum -= (int)(((const char *)buf)[i]);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-09-17 17:20:27 +00:00
|
|
|
static int save_game( void )
|
2007-09-24 22:19:59 +00:00
|
|
|
{
|
|
|
|
int fd = open_save_file( O_CREAT|O_WRONLY|O_TRUNC );
|
|
|
|
int checksum = 42;
|
|
|
|
if( fd < 0 )
|
|
|
|
return -1;
|
|
|
|
if( save_write( fd, &cur_card, sizeof( int ), &checksum )
|
|
|
|
|| save_write( fd, &cur_col, sizeof( int ), &checksum )
|
|
|
|
|| save_write( fd, &sel_card, sizeof( int ), &checksum )
|
|
|
|
|| save_write( fd, deck, NUM_CARDS * sizeof( card_t ), &checksum )
|
|
|
|
|| save_write( fd, &rem, sizeof( int ), &checksum )
|
|
|
|
|| save_write( fd, &cur_rem, sizeof( int ), &checksum )
|
|
|
|
|| save_write( fd, &count_rem, sizeof( int ), &checksum )
|
|
|
|
|| save_write( fd, &cards_per_draw, sizeof( int ), &checksum )
|
|
|
|
|| save_write( fd, cols, COL_NUM * sizeof( int ), &checksum )
|
|
|
|
|| save_write( fd, stacks, SUITS * sizeof( int ), &checksum )
|
2009-01-07 09:53:46 +00:00
|
|
|
|| ( rb->write( fd, &checksum, sizeof( int ) ) < (ssize_t)(sizeof( int ) ) ) )
|
2007-09-24 22:19:59 +00:00
|
|
|
{
|
|
|
|
rb->close( fd );
|
|
|
|
rb->splash( 2*HZ, "Error while saving game. Aborting." );
|
|
|
|
return -2;
|
|
|
|
}
|
|
|
|
rb->close( fd );
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-09-17 17:20:27 +00:00
|
|
|
static int load_game( void )
|
2007-09-24 22:19:59 +00:00
|
|
|
{
|
2009-06-24 21:14:28 +00:00
|
|
|
int checksum, retval;
|
2020-10-08 13:47:40 +00:00
|
|
|
|
2007-09-24 22:19:59 +00:00
|
|
|
int fd = open_save_file( O_RDONLY );
|
|
|
|
if( fd < 0 )
|
|
|
|
return -1;
|
2020-10-08 13:47:40 +00:00
|
|
|
|
2009-06-24 21:14:28 +00:00
|
|
|
retval = 0; /* Assume good case */
|
2017-01-15 23:10:38 +00:00
|
|
|
if( ( rb->lseek( fd, -(off_t)sizeof( int ), SEEK_END ) == -((ssize_t)sizeof( int ))-1 )
|
2009-01-07 09:53:46 +00:00
|
|
|
|| ( rb->read( fd, &checksum, sizeof( int ) ) < ((ssize_t)sizeof( int )) )
|
|
|
|
|| ( rb->lseek( fd, 0, SEEK_SET ) == -1 )
|
2007-09-24 22:19:59 +00:00
|
|
|
|| save_read( fd, &cur_card, sizeof( int ), &checksum )
|
|
|
|
|| save_read( fd, &cur_col, sizeof( int ), &checksum )
|
|
|
|
|| save_read( fd, &sel_card, sizeof( int ), &checksum )
|
|
|
|
|| save_read( fd, deck, NUM_CARDS * sizeof( card_t ), &checksum )
|
|
|
|
|| save_read( fd, &rem, sizeof( int ), &checksum )
|
|
|
|
|| save_read( fd, &cur_rem, sizeof( int ), &checksum )
|
|
|
|
|| save_read( fd, &count_rem, sizeof( int ), &checksum )
|
|
|
|
|| save_read( fd, &cards_per_draw, sizeof( int ), &checksum )
|
|
|
|
|| save_read( fd, cols, COL_NUM * sizeof( int ), &checksum )
|
|
|
|
|| save_read( fd, stacks, SUITS * sizeof( int ), &checksum ) )
|
|
|
|
{
|
|
|
|
rb->splash( 2*HZ, "Error while loading saved game. Aborting." );
|
2009-06-24 21:14:28 +00:00
|
|
|
retval = -2;
|
2007-09-24 22:19:59 +00:00
|
|
|
}
|
2009-06-24 21:14:28 +00:00
|
|
|
else if( checksum != 42 )
|
2007-09-24 22:19:59 +00:00
|
|
|
{
|
|
|
|
rb->splash( 2*HZ, "Save file was corrupted. Aborting." );
|
2009-06-24 21:14:28 +00:00
|
|
|
retval = -3;
|
2007-09-24 22:19:59 +00:00
|
|
|
}
|
2020-10-08 13:47:40 +00:00
|
|
|
|
2009-06-24 21:14:28 +00:00
|
|
|
rb->close( fd );
|
|
|
|
delete_save_file();
|
|
|
|
return retval;
|
2007-09-24 22:19:59 +00:00
|
|
|
}
|
|
|
|
|
2006-09-04 21:33:08 +00:00
|
|
|
/**
|
|
|
|
* The main game loop
|
2007-09-24 22:19:59 +00:00
|
|
|
*
|
|
|
|
* If skipmenu is defined to SOLITAIRE_QUIT, the menu will be skipped and
|
|
|
|
* game will resume.
|
2006-09-04 21:33:08 +00:00
|
|
|
*/
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2011-09-17 17:20:27 +00:00
|
|
|
static int solitaire( int skipmenu )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
int i,j;
|
2011-05-22 13:53:31 +00:00
|
|
|
int button;
|
|
|
|
#ifdef NEED_LASTBUTTON_VAR
|
|
|
|
int lastbutton = 0;
|
|
|
|
#endif
|
2006-09-20 23:34:54 +00:00
|
|
|
int c,h,prevcard;
|
2004-08-17 06:50:14 +00:00
|
|
|
int biggest_col_length;
|
2006-07-11 21:38:27 +00:00
|
|
|
|
2005-06-26 20:12:56 +00:00
|
|
|
rb->srand( *rb->current_tick );
|
2007-09-24 22:19:59 +00:00
|
|
|
if( skipmenu != SOLITAIRE_QUIT )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2007-09-24 22:19:59 +00:00
|
|
|
switch( solitaire_menu(false) )
|
|
|
|
{
|
|
|
|
case MENU_QUIT:
|
2007-09-30 16:39:36 +00:00
|
|
|
return SOLITAIRE_QUIT;
|
2004-10-20 23:54:53 +00:00
|
|
|
|
2007-09-24 22:19:59 +00:00
|
|
|
case MENU_USB:
|
|
|
|
return SOLITAIRE_USB;
|
|
|
|
}
|
|
|
|
solitaire_init();
|
2004-10-20 23:54:53 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
|
|
|
|
while( true )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
rb->lcd_clear_display();
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* get the biggest column length so that display can be "optimized" */
|
2004-08-17 06:50:14 +00:00
|
|
|
biggest_col_length = 0;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
for(i=0;i<COL_NUM;i++)
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
j = 0;
|
|
|
|
c = cols[i];
|
2006-09-29 20:39:29 +00:00
|
|
|
|
|
|
|
if( c != NOT_A_CARD )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2006-09-29 20:39:29 +00:00
|
|
|
while( true )
|
|
|
|
{
|
|
|
|
/* don't include the last card in the column length. */
|
|
|
|
if( deck[c].next == NOT_A_CARD )
|
|
|
|
{
|
|
|
|
break; /* no successor: get outta here. */
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if( deck[c].known )
|
|
|
|
j += 2;
|
|
|
|
else
|
|
|
|
j++;
|
|
|
|
}
|
|
|
|
c = deck[c].next;
|
2007-03-16 00:52:42 +00:00
|
|
|
}
|
2006-09-29 20:39:29 +00:00
|
|
|
/* make column distinguishable from an empty column,
|
|
|
|
* and avoid division by zero while displaying */
|
2007-03-16 00:52:42 +00:00
|
|
|
if( j == 0 )
|
2006-09-29 20:39:29 +00:00
|
|
|
j = 1;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-09-29 20:39:29 +00:00
|
|
|
if( j > biggest_col_length )
|
|
|
|
biggest_col_length = j;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* check if there are cards remaining in the game. */
|
|
|
|
/* if there aren't any, that means you won :) */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( biggest_col_length == 0 && rem == NOT_A_CARD )
|
|
|
|
{
|
2009-06-24 21:19:16 +00:00
|
|
|
rb->lcd_update();
|
2007-03-16 21:56:08 +00:00
|
|
|
rb->splash( HZ, "You Won :)" );
|
2006-09-04 21:33:08 +00:00
|
|
|
return bouncing_cards();
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* draw the columns */
|
2006-08-02 22:17:21 +00:00
|
|
|
for( i = 0; i < COL_NUM; i++ )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
c = cols[i];
|
2005-12-20 22:57:04 +00:00
|
|
|
j = CARD_START;
|
2006-08-02 22:17:21 +00:00
|
|
|
while( true )
|
|
|
|
{
|
|
|
|
if( c == NOT_A_CARD )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
/* draw the cursor on empty columns */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_col == i )
|
|
|
|
{
|
2006-09-29 20:39:29 +00:00
|
|
|
draw_cursor( MARGIN + i * (CARD_WIDTH
|
|
|
|
+(LCD_WIDTH-COL_NUM*CARD_WIDTH-2*MARGIN)/(COL_NUM-1)),
|
|
|
|
j );
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2005-12-20 22:57:04 +00:00
|
|
|
|
2006-09-29 20:39:29 +00:00
|
|
|
draw_card( &deck[c], MARGIN + i * (CARD_WIDTH
|
|
|
|
+(LCD_WIDTH-COL_NUM*CARD_WIDTH-2*MARGIN)/(COL_NUM-1)),
|
|
|
|
j, c == sel_card, c == cur_card );
|
2006-08-02 22:17:21 +00:00
|
|
|
|
|
|
|
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 )
|
2006-09-29 20:39:29 +00:00
|
|
|
j += SYMBOL_HEIGHT;
|
2006-09-02 23:10:28 +00:00
|
|
|
else if( deck[h].known )
|
2006-09-29 20:39:29 +00:00
|
|
|
j += min( SYMBOL_HEIGHT,
|
|
|
|
2 * (LCD_HEIGHT - CARD_START - CARD_HEIGHT - MARGIN)
|
|
|
|
/ biggest_col_length );
|
2006-08-02 22:17:21 +00:00
|
|
|
else
|
2006-09-29 20:39:29 +00:00
|
|
|
j += min( SYMBOL_HEIGHT / 2,
|
|
|
|
(LCD_HEIGHT - CARD_START - CARD_HEIGHT - MARGIN)
|
|
|
|
/ biggest_col_length );
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2005-12-20 22:57:04 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/* draw the stacks */
|
|
|
|
for( i=0; i<SUITS; i++ )
|
|
|
|
{
|
|
|
|
c = find_last_card( STACKS_COL + i );
|
|
|
|
|
|
|
|
if( c != NOT_A_CARD )
|
|
|
|
{
|
2006-09-20 23:34:54 +00:00
|
|
|
draw_card( &deck[c],
|
2006-09-06 01:33:26 +00:00
|
|
|
LCD_WIDTH-(CARD_WIDTH*4+4+MARGIN)+CARD_WIDTH*i+i+1,
|
2006-09-03 14:16:03 +00:00
|
|
|
MARGIN,
|
2006-09-29 20:39:29 +00:00
|
|
|
c == sel_card, cur_col == STACKS_COL + i );
|
2006-07-11 21:38:27 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
draw_empty_stack( i,
|
2006-09-06 01:33:26 +00:00
|
|
|
LCD_WIDTH-(CARD_WIDTH*4+4+MARGIN)+CARD_WIDTH*i+i+1,
|
2006-09-03 14:16:03 +00:00
|
|
|
MARGIN, cur_col == STACKS_COL + i );
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* draw the remains */
|
2006-09-03 16:54:42 +00:00
|
|
|
if( rem != NOT_A_CARD &&
|
|
|
|
( cur_rem == NOT_A_CARD || deck[cur_rem].next != NOT_A_CARD ) )
|
2006-08-03 20:58:35 +00:00
|
|
|
{
|
|
|
|
/* gruik ! (we want to display a card back) */
|
|
|
|
deck[rem].known = false;
|
2006-09-29 20:39:29 +00:00
|
|
|
draw_card( &deck[rem], MARGIN, MARGIN, false, false );
|
2006-08-03 20:58:35 +00:00
|
|
|
deck[rem].known = true;
|
|
|
|
}
|
|
|
|
|
2006-09-10 20:04:17 +00:00
|
|
|
if( rem != NOT_A_CARD && cur_rem != NOT_A_CARD )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2006-09-10 20:04:17 +00:00
|
|
|
if( count_rem < 0 )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2006-09-10 20:04:17 +00:00
|
|
|
prevcard = rem;
|
|
|
|
count_rem = 0;
|
|
|
|
while( prevcard != cur_rem && count_rem < cards_per_draw-1 )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
|
|
|
prevcard = deck[prevcard].next;
|
2006-09-10 20:04:17 +00:00
|
|
|
count_rem++;
|
2006-07-11 21:38:27 +00:00
|
|
|
}
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
2006-09-10 20:04:17 +00:00
|
|
|
prevcard = cur_rem;
|
|
|
|
j = CARD_WIDTH+2*MARGIN+1;
|
|
|
|
for( i = 0; i < count_rem; i++ )
|
|
|
|
prevcard = find_prev_card(prevcard);
|
|
|
|
for( i = 0; i <= count_rem; i++ )
|
|
|
|
{
|
2006-09-20 23:34:54 +00:00
|
|
|
draw_card( &deck[prevcard], j,
|
2006-09-10 20:04:17 +00:00
|
|
|
MARGIN, sel_card == prevcard,
|
2006-09-29 20:39:29 +00:00
|
|
|
cur_card == prevcard );
|
2006-09-10 20:04:17 +00:00
|
|
|
prevcard = deck[prevcard].next;
|
2006-09-29 20:39:29 +00:00
|
|
|
j += CARD_WIDTH/2;
|
2006-09-10 20:04:17 +00:00
|
|
|
}
|
2006-09-05 21:47:31 +00:00
|
|
|
}
|
|
|
|
if( ( cur_rem == NOT_A_CARD || rem == NOT_A_CARD )
|
|
|
|
&& cur_col == REM_COL )
|
|
|
|
{
|
|
|
|
draw_cursor( CARD_WIDTH+2*MARGIN+1, MARGIN );
|
2006-08-02 22:33:34 +00:00
|
|
|
}
|
2006-07-11 21:38:27 +00:00
|
|
|
|
2004-08-17 06:50:14 +00:00
|
|
|
rb->lcd_update();
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* what to do when a key is pressed ... */
|
2006-08-02 22:17:21 +00:00
|
|
|
button = rb->button_get( true );
|
2009-07-05 16:13:20 +00:00
|
|
|
#if (CONFIG_KEYPAD == SANSA_E200_PAD) || (CONFIG_KEYPAD == SANSA_FUZE_PAD)
|
2008-01-10 08:08:31 +00:00
|
|
|
if (button&(BUTTON_SCROLL_BACK|BUTTON_SCROLL_FWD))
|
2007-05-15 14:08:17 +00:00
|
|
|
button = button & (~BUTTON_REPEAT);
|
|
|
|
#endif
|
2006-08-02 22:17:21 +00:00
|
|
|
switch( button )
|
|
|
|
{
|
|
|
|
/* move cursor to the last card of the previous column
|
|
|
|
* or to the previous final stack
|
|
|
|
* or to the remains stack */
|
2004-10-20 23:54:53 +00:00
|
|
|
case SOL_RIGHT:
|
|
|
|
#ifdef SOL_RIGHT_PRE
|
2006-08-02 22:17:21 +00:00
|
|
|
if( lastbutton != SOL_RIGHT_PRE )
|
2004-10-20 23:54:53 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_col >= COL_NUM )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_col = 0;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else if( cur_col == COL_NUM - 1 )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_col = REM_COL;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_col = (cur_col+1)%(REM_COL+1);
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
if(cur_col == REM_COL)
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_card = cur_rem;
|
|
|
|
break;
|
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
cur_card = find_last_card( cur_col );
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/* move cursor to the last card of the next column
|
|
|
|
* or to the next final stack
|
|
|
|
* or to the remains stack */
|
2004-10-20 23:54:53 +00:00
|
|
|
case SOL_LEFT:
|
|
|
|
#ifdef SOL_LEFT_PRE
|
2006-08-02 22:17:21 +00:00
|
|
|
if( lastbutton != SOL_LEFT_PRE )
|
2004-10-20 23:54:53 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_col == 0 )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_col = REM_COL;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else if( cur_col >= COL_NUM )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_col = COL_NUM - 1;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_col = (cur_col + REM_COL)%(REM_COL+1);
|
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_col == REM_COL )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_card = cur_rem;
|
|
|
|
break;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
cur_card = find_last_card( cur_col );
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* move cursor to card that's bellow */
|
2004-10-20 23:54:53 +00:00
|
|
|
case SOL_DOWN:
|
|
|
|
#ifdef SOL_DOWN_PRE
|
2006-08-02 22:17:21 +00:00
|
|
|
if( lastbutton != SOL_DOWN_PRE )
|
2004-10-20 23:54:53 +00:00
|
|
|
break;
|
2006-09-17 22:14:18 +00:00
|
|
|
#else
|
|
|
|
case SOL_DOWN|BUTTON_REPEAT:
|
2004-10-20 23:54:53 +00:00
|
|
|
#endif
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_col >= COL_NUM )
|
|
|
|
{
|
2005-10-06 12:42:19 +00:00
|
|
|
cur_col = (cur_col - COL_NUM + 1)%(SUITS + 1) + COL_NUM;
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_col == REM_COL )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_card = cur_rem;
|
2006-07-11 21:38:27 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
cur_card = find_last_card( cur_col );
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_card == NOT_A_CARD ) break;
|
|
|
|
if( deck[cur_card].next != NOT_A_CARD )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
cur_card = deck[cur_card].next;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
cur_card = cols[cur_col];
|
2006-09-20 23:34:54 +00:00
|
|
|
while( !deck[ cur_card].known
|
2006-08-02 22:17:21 +00:00
|
|
|
&& deck[cur_card].next != NOT_A_CARD )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_card = deck[cur_card].next;
|
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
break;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* move cursor to card that's above */
|
2004-10-20 23:54:53 +00:00
|
|
|
case SOL_UP:
|
|
|
|
#ifdef SOL_UP_PRE
|
2006-08-02 22:17:21 +00:00
|
|
|
if( lastbutton != SOL_UP_PRE )
|
2004-10-20 23:54:53 +00:00
|
|
|
break;
|
2006-09-17 22:14:18 +00:00
|
|
|
#else
|
|
|
|
case SOL_UP|BUTTON_REPEAT:
|
2004-10-20 23:54:53 +00:00
|
|
|
#endif
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_col >= COL_NUM )
|
|
|
|
{
|
2005-10-06 12:42:19 +00:00
|
|
|
cur_col = (cur_col - COL_NUM + SUITS)%(SUITS + 1) + COL_NUM;
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_col == REM_COL )
|
|
|
|
{
|
2004-08-21 23:05:36 +00:00
|
|
|
cur_card = cur_rem;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cur_card = find_last_card( cur_col );
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2004-08-21 23:05:36 +00:00
|
|
|
break;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
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 );
|
2004-08-21 23:05:36 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
} while( deck[cur_card].next != NOT_A_CARD
|
2006-09-20 23:34:54 +00:00
|
|
|
&& !deck[cur_card].known );
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
2004-10-20 23:54:53 +00:00
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* Try to put card under cursor on one of the stacks */
|
2004-10-20 23:54:53 +00:00
|
|
|
case SOL_CUR2STACK:
|
|
|
|
#ifdef SOL_CUR2STACK_PRE
|
2006-08-02 22:17:21 +00:00
|
|
|
if( lastbutton != SOL_CUR2STACK_PRE )
|
2004-10-20 23:54:53 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2006-09-10 20:04:17 +00:00
|
|
|
move_card( deck[cur_card].suit + STACKS_COL, cur_card );
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
2004-10-20 23:54:53 +00:00
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* Move cards arround, Uncover cards, ... */
|
2004-10-20 23:54:53 +00:00
|
|
|
case SOL_MOVE:
|
|
|
|
#ifdef SOL_MOVE_PRE
|
2006-08-02 22:17:21 +00:00
|
|
|
if( lastbutton != SOL_MOVE_PRE )
|
2004-10-20 23:54:53 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2005-12-20 22:57:04 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
if( sel_card == NOT_A_CARD )
|
|
|
|
{
|
|
|
|
if( cur_card != NOT_A_CARD )
|
|
|
|
{
|
|
|
|
if( deck[cur_card].next == NOT_A_CARD
|
2006-09-20 23:34:54 +00:00
|
|
|
&& !deck[cur_card].known )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
|
|
|
/* reveal a hidden card */
|
2006-09-20 23:34:54 +00:00
|
|
|
deck[cur_card].known = true;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else if( cur_col == REM_COL && cur_rem == NOT_A_CARD )
|
|
|
|
{
|
2005-12-20 22:57:04 +00:00
|
|
|
break;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* select a card */
|
2004-08-21 23:05:36 +00:00
|
|
|
sel_card = cur_card;
|
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else if( sel_card == cur_card )
|
|
|
|
{
|
|
|
|
/* unselect card or try putting card on
|
|
|
|
* one of the 4 stacks */
|
2006-09-10 20:04:17 +00:00
|
|
|
if( move_card( deck[sel_card].suit + COL_NUM, sel_card )
|
|
|
|
== MOVE_OK && cur_col == REM_COL )
|
2006-07-11 21:38:27 +00:00
|
|
|
{
|
|
|
|
cur_card = cur_rem;
|
|
|
|
}
|
2006-09-10 20:04:17 +00:00
|
|
|
sel_card = NOT_A_CARD;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
/* try moving cards */
|
2008-03-08 13:51:03 +00:00
|
|
|
/* The flexible move must not be used from the remains stack. */
|
|
|
|
if (find_card_col(sel_card) == REM_COL)
|
2007-04-23 14:15:07 +00:00
|
|
|
{
|
|
|
|
if (move_card( cur_col, sel_card ) == MOVE_NOT_OK)
|
|
|
|
sel_card = NOT_A_CARD;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
do {
|
2008-03-08 13:51:03 +00:00
|
|
|
if (move_card( cur_col, sel_card) == MOVE_OK)
|
|
|
|
break;
|
|
|
|
sel_card = find_prev_card(sel_card);
|
|
|
|
} while (sel_card != NOT_A_CARD);
|
2007-04-23 14:15:07 +00:00
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
break;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/* If the card on the top of the remains can be put where
|
|
|
|
* the cursor is, go ahead */
|
2004-10-20 23:54:53 +00:00
|
|
|
case SOL_REM2CUR:
|
|
|
|
#ifdef SOL_REM2CUR_PRE
|
2006-08-02 22:17:21 +00:00
|
|
|
if( lastbutton != SOL_REM2CUR_PRE )
|
2004-10-20 23:54:53 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2006-09-10 20:04:17 +00:00
|
|
|
move_card( cur_col, cur_rem );
|
2004-08-17 06:50:14 +00:00
|
|
|
break;
|
2004-10-20 23:54:53 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/* If the card on top of the remains can be put on one
|
|
|
|
* of the stacks, do so */
|
2004-10-20 23:54:53 +00:00
|
|
|
case SOL_REM2STACK:
|
|
|
|
#ifdef SOL_REM2STACK_PRE
|
2006-08-02 22:17:21 +00:00
|
|
|
if( lastbutton != SOL_REM2STACK_PRE )
|
2004-10-20 23:54:53 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2006-09-10 20:04:17 +00:00
|
|
|
move_card( deck[cur_rem].suit + COL_NUM, cur_rem );
|
2004-08-21 23:05:36 +00:00
|
|
|
break;
|
2004-10-20 23:54:53 +00:00
|
|
|
|
2005-12-20 22:57:04 +00:00
|
|
|
#ifdef SOL_REM
|
2006-07-11 21:38:27 +00:00
|
|
|
case SOL_REM:
|
2006-08-02 22:17:21 +00:00
|
|
|
if( sel_card != NOT_A_CARD )
|
|
|
|
{
|
2005-12-20 22:57:04 +00:00
|
|
|
/* unselect selected card */
|
|
|
|
sel_card = NOT_A_CARD;
|
|
|
|
break;
|
2006-07-11 21:38:27 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
if( rem != NOT_A_CARD && cur_rem != NOT_A_CARD )
|
|
|
|
{
|
2006-09-02 21:56:22 +00:00
|
|
|
sel_card = cur_rem;
|
2006-08-02 22:17:21 +00:00
|
|
|
break;
|
2005-12-20 22:57:04 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
#endif
|
2006-07-11 21:38:27 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/* unselect selected card or ...
|
|
|
|
* draw new cards from the remains of the deck */
|
2004-10-20 23:54:53 +00:00
|
|
|
case SOL_DRAW:
|
|
|
|
#ifdef SOL_DRAW_PRE
|
2006-08-02 22:17:21 +00:00
|
|
|
if( lastbutton != SOL_DRAW_PRE )
|
2004-10-20 23:54:53 +00:00
|
|
|
break;
|
|
|
|
#endif
|
2006-08-02 22:17:21 +00:00
|
|
|
if( sel_card != NOT_A_CARD )
|
|
|
|
{
|
2004-08-18 12:06:10 +00:00
|
|
|
/* unselect selected card */
|
2004-08-17 06:50:14 +00:00
|
|
|
sel_card = NOT_A_CARD;
|
2004-08-21 23:05:36 +00:00
|
|
|
break;
|
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
if( rem != NOT_A_CARD )
|
|
|
|
{
|
2005-06-26 19:35:29 +00:00
|
|
|
int cur_rem_old = cur_rem;
|
2006-09-04 19:36:09 +00:00
|
|
|
count_rem = -1;
|
2004-08-18 12:06:10 +00:00
|
|
|
/* draw new cards form the remains of the deck */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_rem == NOT_A_CARD )
|
|
|
|
{
|
|
|
|
/*if the cursor card is null*/
|
2004-08-17 06:50:14 +00:00
|
|
|
cur_rem = rem;
|
2006-08-02 22:17:21 +00:00
|
|
|
i = cards_per_draw - 1;
|
2006-09-02 21:56:22 +00:00
|
|
|
count_rem++;
|
2006-08-02 22:17:21 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
i = cards_per_draw;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-07-11 21:38:27 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
while( i > 0 && deck[cur_rem].next != NOT_A_CARD )
|
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
cur_rem = deck[cur_rem].next;
|
|
|
|
i--;
|
2006-09-02 21:56:22 +00:00
|
|
|
count_rem++;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
/* test if any cards are really left on
|
|
|
|
* the remains' stack */
|
2006-09-04 19:36:09 +00:00
|
|
|
if( i == cards_per_draw )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2004-08-17 06:50:14 +00:00
|
|
|
cur_rem = NOT_A_CARD;
|
2006-09-04 19:36:09 +00:00
|
|
|
count_rem = -1;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2005-06-26 19:35:29 +00:00
|
|
|
/* if cursor was on remains' stack when new cards were
|
|
|
|
* drawn, put cursor on top of remains' stack */
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_col == REM_COL && cur_card == cur_rem_old )
|
|
|
|
{
|
2005-06-26 19:35:29 +00:00
|
|
|
cur_card = cur_rem;
|
2005-12-20 22:57:04 +00:00
|
|
|
sel_card = NOT_A_CARD;
|
2006-07-11 21:38:27 +00:00
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
break;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-08-21 23:05:36 +00:00
|
|
|
/* Show the menu */
|
2006-06-30 16:43:47 +00:00
|
|
|
#ifdef SOL_RC_QUIT
|
|
|
|
case SOL_RC_QUIT:
|
|
|
|
#endif
|
2004-10-20 23:54:53 +00:00
|
|
|
case SOL_QUIT:
|
2006-09-18 00:36:09 +00:00
|
|
|
switch( solitaire_menu(true) )
|
2006-08-02 22:17:21 +00:00
|
|
|
{
|
2007-09-30 16:39:36 +00:00
|
|
|
case MENU_SAVE_AND_QUIT:
|
|
|
|
return SOLITAIRE_SAVE_AND_QUIT;
|
|
|
|
|
2004-08-17 06:50:14 +00:00
|
|
|
case MENU_QUIT:
|
2004-08-21 23:05:36 +00:00
|
|
|
return SOLITAIRE_QUIT;
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2004-10-20 23:54:53 +00:00
|
|
|
case MENU_USB:
|
|
|
|
return SOLITAIRE_USB;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2006-08-02 22:17:21 +00:00
|
|
|
break;
|
|
|
|
|
2007-08-10 22:48:55 +00:00
|
|
|
case SYS_POWEROFF:
|
2007-09-30 16:39:36 +00:00
|
|
|
return SOLITAIRE_SAVE_AND_QUIT;
|
2007-09-24 22:19:59 +00:00
|
|
|
|
2004-10-20 23:54:53 +00:00
|
|
|
default:
|
2006-08-02 22:17:21 +00:00
|
|
|
if( rb->default_event_handler( button ) == SYS_USB_CONNECTED )
|
2004-10-20 23:54:53 +00:00
|
|
|
return SOLITAIRE_USB;
|
|
|
|
break;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2011-05-22 13:53:31 +00:00
|
|
|
#ifdef NEED_LASTBUTTON_VAR
|
2011-05-22 14:10:05 +00:00
|
|
|
if( button != BUTTON_NONE )
|
2004-10-20 23:54:53 +00:00
|
|
|
lastbutton = button;
|
2011-05-22 13:53:31 +00:00
|
|
|
#endif
|
2004-08-21 23:05:36 +00:00
|
|
|
|
|
|
|
/* fix incoherences concerning cur_col and cur_card */
|
2006-08-02 22:17:21 +00:00
|
|
|
c = find_card_col( cur_card );
|
|
|
|
if( c != NOT_A_COL && c != cur_col )
|
|
|
|
cur_card = find_last_card( cur_col );
|
2005-06-26 19:35:29 +00:00
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
if( cur_card == NOT_A_CARD
|
|
|
|
&& find_last_card( cur_col ) != NOT_A_CARD )
|
|
|
|
cur_card = find_last_card( cur_col );
|
2008-12-13 07:36:44 +00:00
|
|
|
|
|
|
|
rb->yield();
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/**
|
|
|
|
* Plugin entry point
|
|
|
|
*/
|
|
|
|
|
2009-01-16 10:34:40 +00:00
|
|
|
enum plugin_status plugin_start(const void* parameter )
|
2004-08-17 06:50:14 +00:00
|
|
|
{
|
2004-10-20 23:54:53 +00:00
|
|
|
int result;
|
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* plugin init */
|
2004-08-17 06:50:14 +00:00
|
|
|
(void)parameter;
|
2005-12-20 22:57:04 +00:00
|
|
|
|
2006-10-23 22:44:46 +00:00
|
|
|
configfile_load(CONFIG_FILENAME, config,
|
|
|
|
sizeof(config) / sizeof(config[0]), CFGFILE_VERSION);
|
|
|
|
rb->memcpy(&sol, &sol_disk, sizeof(sol)); /* copy to running config */
|
|
|
|
|
2007-09-24 22:19:59 +00:00
|
|
|
if( load_game() == 0 )
|
2007-09-30 16:39:36 +00:00
|
|
|
{
|
|
|
|
rb->splash( HZ, "Resuming saved game." );
|
2007-09-24 22:19:59 +00:00
|
|
|
result = SOLITAIRE_QUIT;
|
2007-09-30 16:39:36 +00:00
|
|
|
}
|
2007-09-24 22:19:59 +00:00
|
|
|
else
|
|
|
|
result = SOLITAIRE_WIN;
|
|
|
|
|
2006-08-02 22:17:21 +00:00
|
|
|
/* play the game :)
|
|
|
|
* Keep playing if a game was won (that means display the menu after
|
|
|
|
* winning instead of quiting) */
|
2007-09-24 22:19:59 +00:00
|
|
|
while( ( result = solitaire( result ) ) == SOLITAIRE_WIN );
|
|
|
|
|
2009-06-24 21:14:28 +00:00
|
|
|
if( result != SOLITAIRE_QUIT )
|
|
|
|
/* result == SOLITAIRE_USB || result == SOLITAIRE_SAVE_AND_QUIT */
|
2007-09-30 16:39:36 +00:00
|
|
|
save_game();
|
2007-03-16 00:52:42 +00:00
|
|
|
|
2006-10-23 22:44:46 +00:00
|
|
|
if (rb->memcmp(&sol, &sol_disk, sizeof(sol))) /* save settings if changed */
|
2006-09-15 06:24:36 +00:00
|
|
|
{
|
2006-10-23 22:44:46 +00:00
|
|
|
rb->memcpy(&sol_disk, &sol, sizeof(sol));
|
|
|
|
configfile_save(CONFIG_FILENAME, config,
|
|
|
|
sizeof(config) / sizeof(config[0]), CFGFILE_VERSION);
|
2006-09-15 06:24:36 +00:00
|
|
|
}
|
2004-08-17 06:50:14 +00:00
|
|
|
|
2004-08-18 12:06:10 +00:00
|
|
|
/* Exit the plugin */
|
2006-08-02 22:17:21 +00:00
|
|
|
return ( result == SOLITAIRE_USB ) ? PLUGIN_USB_CONNECTED : PLUGIN_OK;
|
2004-08-17 06:50:14 +00:00
|
|
|
}
|