2006-03-12 09:35:53 +00:00
|
|
|
/***************************************************************************
|
|
|
|
* __________ __ ___.
|
|
|
|
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
|
|
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
|
|
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
|
|
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
|
|
* \/ \/ \/ \/ \/
|
|
|
|
* $Id$
|
|
|
|
*
|
|
|
|
* Copyright (C) 2006 Eli Sherer
|
2007-06-03 17:34:23 +00:00
|
|
|
* 2007 Antoine Cellerier
|
2006-03-12 09:35:53 +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.
|
2006-03-12 09:35:53 +00:00
|
|
|
*
|
|
|
|
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
|
|
* KIND, either express or implied.
|
|
|
|
*
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "plugin.h"
|
2008-11-20 11:27:31 +00:00
|
|
|
#include "lib/helper.h"
|
2009-02-26 17:10:27 +00:00
|
|
|
#include "lib/playback_control.h"
|
2014-04-23 21:25:05 +00:00
|
|
|
#include "lib/highscore.h"
|
2006-03-12 09:35:53 +00:00
|
|
|
|
2010-08-24 14:30:46 +00:00
|
|
|
|
2006-03-12 09:35:53 +00:00
|
|
|
|
|
|
|
#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD)
|
|
|
|
|
|
|
|
#define QUIT BUTTON_OFF
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define PAUSE BUTTON_MODE
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
|
2006-06-30 16:43:47 +00:00
|
|
|
#define RC_QUIT BUTTON_RC_STOP
|
|
|
|
|
2007-01-14 13:48:09 +00:00
|
|
|
#elif (CONFIG_KEYPAD == ARCHOS_AV300_PAD)
|
|
|
|
|
|
|
|
#define QUIT BUTTON_OFF
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define PAUSE BUTTON_ON
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
|
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-03-12 09:35:53 +00:00
|
|
|
|
|
|
|
#define QUIT (BUTTON_SELECT | BUTTON_MENU)
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define PAUSE BUTTON_SELECT
|
2006-05-23 03:33:02 +00:00
|
|
|
#define MENU_UP BUTTON_SCROLL_FWD
|
|
|
|
#define MENU_DOWN BUTTON_SCROLL_BACK
|
2006-03-12 09:35:53 +00:00
|
|
|
#define UP BUTTON_MENU
|
|
|
|
#define DOWN BUTTON_PLAY
|
|
|
|
|
2007-03-16 23:02:39 +00:00
|
|
|
#elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD
|
2006-03-12 09:35:53 +00:00
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
|
|
|
#elif (CONFIG_KEYPAD == GIGABEAT_PAD)
|
|
|
|
|
2007-05-19 23:38:09 +00:00
|
|
|
#define QUIT BUTTON_POWER
|
2006-03-12 09:35:53 +00:00
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
2007-05-19 23:38:09 +00:00
|
|
|
#define PAUSE BUTTON_A
|
2006-03-12 09:35:53 +00:00
|
|
|
|
2007-09-20 10:49:48 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_E200_PAD) || \
|
|
|
|
(CONFIG_KEYPAD == SANSA_C200_PAD)
|
2006-10-26 13:38:09 +00:00
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_REC
|
|
|
|
|
2009-04-10 17:28:26 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_CLIP_PAD)
|
2008-11-28 00:37:28 +00:00
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_HOME
|
|
|
|
|
2009-04-10 17:28:26 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_FUZE_PAD)
|
|
|
|
|
|
|
|
#define QUIT (BUTTON_HOME|BUTTON_REPEAT)
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_SELECT
|
|
|
|
|
2008-12-12 19:50:49 +00:00
|
|
|
#elif (CONFIG_KEYPAD == SANSA_M200_PAD)
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_SELECT
|
2008-11-28 00:37:28 +00:00
|
|
|
|
2006-08-03 20:17:25 +00:00
|
|
|
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_SCROLL_UP
|
|
|
|
#define DOWN BUTTON_SCROLL_DOWN
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
2007-06-05 21:49:51 +00:00
|
|
|
#elif CONFIG_KEYPAD == RECORDER_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_OFF
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
|
|
|
#elif CONFIG_KEYPAD == ONDIO_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_OFF
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define PAUSE BUTTON_MENU
|
|
|
|
|
2008-02-17 12:23:02 +00:00
|
|
|
#elif (CONFIG_KEYPAD == GIGABEAT_S_PAD)
|
|
|
|
|
|
|
|
#define QUIT BUTTON_BACK
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
2008-03-01 22:55:09 +00:00
|
|
|
#elif (CONFIG_KEYPAD == MROBE100_PAD)
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_DISPLAY
|
|
|
|
|
2008-03-22 10:24:28 +00:00
|
|
|
#elif CONFIG_KEYPAD == IAUDIO_M3_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_RC_REC
|
|
|
|
#define LEFT BUTTON_RC_REW
|
|
|
|
#define RIGHT BUTTON_RC_FF
|
|
|
|
#define UP BUTTON_RC_VOL_UP
|
|
|
|
#define DOWN BUTTON_RC_VOL_DOWN
|
|
|
|
#define PAUSE BUTTON_RC_PLAY
|
|
|
|
|
2009-12-15 20:51:41 +00:00
|
|
|
#elif CONFIG_KEYPAD == COWON_D2_PAD
|
2008-03-22 22:03:34 +00:00
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
|
2008-10-07 16:38:28 +00:00
|
|
|
#elif CONFIG_KEYPAD == IAUDIO67_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_STOP
|
|
|
|
#define DOWN BUTTON_PLAY
|
|
|
|
#define PAUSE BUTTON_MENU
|
|
|
|
|
2008-12-04 21:28:56 +00:00
|
|
|
#elif CONFIG_KEYPAD == CREATIVEZVM_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_BACK
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
2008-12-08 09:51:42 +00:00
|
|
|
#define PAUSE BUTTON_PLAY
|
2008-12-04 21:28:56 +00:00
|
|
|
|
2014-03-21 21:16:02 +00:00
|
|
|
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI3_PAD
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_BACK
|
|
|
|
#define RIGHT BUTTON_MENU
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
2009-01-24 22:41:55 +00:00
|
|
|
#elif CONFIG_KEYPAD == PHILIPS_HDD1630_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_VIEW
|
|
|
|
|
2010-11-02 03:29:16 +00:00
|
|
|
#elif CONFIG_KEYPAD == PHILIPS_HDD6330_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_PREV
|
|
|
|
#define RIGHT BUTTON_NEXT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_MENU
|
|
|
|
|
2009-12-02 01:56:39 +00:00
|
|
|
#elif CONFIG_KEYPAD == PHILIPS_SA9200_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_PREV
|
|
|
|
#define RIGHT BUTTON_NEXT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_MENU
|
|
|
|
|
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 QUIT BUTTON_POWER
|
|
|
|
|
2014-05-22 21:34:52 +00:00
|
|
|
#elif CONFIG_KEYPAD == SAMSUNG_YH820_PAD || \
|
2016-01-23 14:54:08 +00:00
|
|
|
CONFIG_KEYPAD == SAMSUNG_YH92X_PAD
|
2009-08-04 03:08:32 +00:00
|
|
|
|
2015-07-19 23:50:26 +00:00
|
|
|
#define QUIT BUTTON_REW
|
2009-08-04 03:08:32 +00:00
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
2014-10-15 12:25:28 +00:00
|
|
|
#define PAUSE BUTTON_PLAY
|
2009-08-04 03:08:32 +00:00
|
|
|
|
2010-02-13 15:46:34 +00:00
|
|
|
#elif CONFIG_KEYPAD == PBELL_VIBE500_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_REC
|
|
|
|
#define LEFT BUTTON_PREV
|
|
|
|
#define RIGHT BUTTON_NEXT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
2010-04-26 21:40:00 +00:00
|
|
|
#elif CONFIG_KEYPAD == MPIO_HD200_PAD
|
|
|
|
|
|
|
|
#define QUIT (BUTTON_REC|BUTTON_PLAY)
|
|
|
|
#define LEFT BUTTON_VOL_DOWN
|
|
|
|
#define RIGHT BUTTON_VOL_UP
|
2010-11-02 10:44:34 +00:00
|
|
|
#define UP BUTTON_REW
|
|
|
|
#define DOWN BUTTON_FF
|
2010-04-26 21:40:00 +00:00
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
2010-11-30 10:52:14 +00:00
|
|
|
#elif CONFIG_KEYPAD == MPIO_HD300_PAD
|
|
|
|
|
2012-02-02 13:42:42 +00:00
|
|
|
#define QUIT (BUTTON_MENU | BUTTON_REPEAT)
|
|
|
|
#define LEFT BUTTON_REW
|
|
|
|
#define RIGHT BUTTON_FF
|
2010-11-30 10:52:14 +00:00
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
2011-10-02 16:04:57 +00:00
|
|
|
#elif CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_PLAYPAUSE
|
|
|
|
|
2011-11-16 14:08:01 +00:00
|
|
|
#elif CONFIG_KEYPAD == SANSA_CONNECT_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_SELECT
|
|
|
|
|
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 QUIT BUTTON_BACK
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_SELECT
|
|
|
|
|
2012-04-06 16:17:27 +00:00
|
|
|
#elif (CONFIG_KEYPAD == HM60X_PAD) || \
|
|
|
|
(CONFIG_KEYPAD == HM801_PAD)
|
2012-03-23 18:32:50 +00:00
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_SELECT
|
|
|
|
|
2014-06-30 18:24:15 +00:00
|
|
|
#elif CONFIG_KEYPAD == SONY_NWZ_PAD
|
|
|
|
#define QUIT BUTTON_BACK
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
2014-07-17 08:40:17 +00:00
|
|
|
#elif CONFIG_KEYPAD == CREATIVE_ZEN_PAD
|
|
|
|
#define QUIT BUTTON_BACK
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_PLAYPAUSE
|
|
|
|
|
2014-08-30 11:15:53 +00:00
|
|
|
#elif CONFIG_KEYPAD == DX50_PAD
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_VOL_UP
|
|
|
|
#define DOWN BUTTON_VOL_DOWN
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
2018-02-22 22:42:29 +00:00
|
|
|
#elif CONFIG_KEYPAD == CREATIVE_ZENXFI2_PAD
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define PAUSE BUTTON_MENU
|
|
|
|
|
2018-03-02 20:53:55 +00:00
|
|
|
#elif CONFIG_KEYPAD == AGPTEK_ROCKER_PAD
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_LEFT
|
|
|
|
#define RIGHT BUTTON_RIGHT
|
|
|
|
#define UP BUTTON_UP
|
|
|
|
#define DOWN BUTTON_DOWN
|
|
|
|
#define PAUSE BUTTON_SELECT
|
|
|
|
|
2018-06-28 10:24:26 +00:00
|
|
|
#elif CONFIG_KEYPAD == XDUOO_X3_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_PREV
|
|
|
|
#define RIGHT BUTTON_NEXT
|
|
|
|
#define UP BUTTON_HOME
|
|
|
|
#define DOWN BUTTON_OPTION
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
2018-06-29 20:09:28 +00:00
|
|
|
#elif CONFIG_KEYPAD == IHIFI_770_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_HOME
|
|
|
|
#define RIGHT BUTTON_VOL_DOWN
|
|
|
|
#define UP BUTTON_PREV
|
|
|
|
#define DOWN BUTTON_NEXT
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
|
|
|
#elif CONFIG_KEYPAD == IHIFI_800_PAD
|
|
|
|
|
|
|
|
#define QUIT BUTTON_POWER
|
|
|
|
#define LEFT BUTTON_HOME
|
|
|
|
#define RIGHT BUTTON_VOL_DOWN
|
|
|
|
#define UP BUTTON_PREV
|
|
|
|
#define DOWN BUTTON_NEXT
|
|
|
|
#define PAUSE BUTTON_PLAY
|
|
|
|
|
2006-03-12 09:35:53 +00:00
|
|
|
#else
|
2008-03-01 22:55:09 +00:00
|
|
|
#error No keymap defined!
|
2006-03-12 09:35:53 +00:00
|
|
|
#endif
|
|
|
|
|
2008-08-23 09:46:38 +00:00
|
|
|
#ifdef HAVE_TOUCHSCREEN
|
2008-04-27 15:30:19 +00:00
|
|
|
#ifndef QUIT
|
|
|
|
#define QUIT BUTTON_TOPLEFT
|
|
|
|
#endif
|
|
|
|
#ifndef LEFT
|
|
|
|
#define LEFT BUTTON_MIDLEFT
|
|
|
|
#endif
|
|
|
|
#ifndef RIGHT
|
|
|
|
#define RIGHT BUTTON_MIDRIGHT
|
|
|
|
#endif
|
|
|
|
#ifndef UP
|
|
|
|
#define UP BUTTON_TOPMIDDLE
|
|
|
|
#endif
|
|
|
|
#ifndef DOWN
|
|
|
|
#define DOWN BUTTON_BOTTOMMIDDLE
|
|
|
|
#endif
|
|
|
|
#ifndef PAUSE
|
|
|
|
#define PAUSE BUTTON_CENTER
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
2006-03-12 09:35:53 +00:00
|
|
|
#define MOVE_NO 0 /* player movement */
|
|
|
|
#define MOVE_UP 1 /* 1 */
|
|
|
|
#define MOVE_DN 2 /* 3 0 4 */
|
|
|
|
#define MOVE_LT 3 /* 2 */
|
|
|
|
#define MOVE_RT 4
|
|
|
|
|
2007-06-03 17:34:23 +00:00
|
|
|
/* ball movement (12 ways) */
|
|
|
|
/* UUL UR */
|
|
|
|
/* UL UR */
|
|
|
|
/* ULL . URR */
|
|
|
|
/* DLL DRR */
|
|
|
|
/* DL DR */
|
|
|
|
/* DDL DDR */
|
|
|
|
|
|
|
|
#define DIR_UU (1<<7)
|
|
|
|
#define DIR_U (1<<6)
|
|
|
|
#define DIR_RR (1<<5)
|
|
|
|
#define DIR_R (1<<4)
|
|
|
|
#define DIR_DD (1<<3)
|
|
|
|
#define DIR_D (1<<2)
|
|
|
|
#define DIR_LL (1<<1)
|
|
|
|
#define DIR_L (1<<0)
|
|
|
|
|
|
|
|
#define MOVE_UUR ( DIR_UU | DIR_R )
|
|
|
|
#define MOVE_UR ( DIR_U | DIR_R )
|
|
|
|
#define MOVE_URR ( DIR_U | DIR_RR )
|
|
|
|
#define MOVE_DRR ( DIR_D | DIR_RR )
|
|
|
|
#define MOVE_DR ( DIR_D | DIR_R )
|
|
|
|
#define MOVE_DDR ( DIR_DD | DIR_R )
|
|
|
|
#define MOVE_DDL ( DIR_DD | DIR_L )
|
|
|
|
#define MOVE_DL ( DIR_D | DIR_L )
|
|
|
|
#define MOVE_DLL ( DIR_D | DIR_LL )
|
|
|
|
#define MOVE_ULL ( DIR_U | DIR_LL )
|
|
|
|
#define MOVE_UL ( DIR_U | DIR_L )
|
|
|
|
#define MOVE_UUL ( DIR_UU | DIR_L )
|
2006-03-12 09:35:53 +00:00
|
|
|
|
2007-06-05 21:49:51 +00:00
|
|
|
#if (LCD_WIDTH>112) && (LCD_HEIGHT>64)
|
|
|
|
# define CUBE_SIZE 8 /* 8x22=176 */
|
|
|
|
# define pos(a) ((a)>>3)
|
|
|
|
#else
|
|
|
|
# define CUBE_SIZE 4
|
|
|
|
# define pos(a) ((a)>>2)
|
|
|
|
#endif
|
|
|
|
|
2006-03-12 09:35:53 +00:00
|
|
|
#define STARTING_QIXES 2
|
|
|
|
#define MAX_LEVEL 10
|
|
|
|
#define MAX_QIXES MAX_LEVEL+STARTING_QIXES
|
2007-06-06 20:48:01 +00:00
|
|
|
#define BOARD_W ((int)(LCD_WIDTH/CUBE_SIZE))
|
|
|
|
#define BOARD_H ((int)(LCD_HEIGHT/CUBE_SIZE))
|
2006-03-12 09:35:53 +00:00
|
|
|
#define BOARD_X (LCD_WIDTH-BOARD_W*CUBE_SIZE)/2
|
|
|
|
#define BOARD_Y (LCD_HEIGHT-BOARD_H*CUBE_SIZE)/2
|
|
|
|
|
|
|
|
#ifdef HAVE_LCD_COLOR
|
2006-05-23 03:57:35 +00:00
|
|
|
#define CLR_RED LCD_RGBPACK(255,0,0) /* used to imply danger */
|
|
|
|
#define CLR_LTBLUE LCD_RGBPACK(125, 145, 180) /* used for frame and filling */
|
|
|
|
#define PLR_COL LCD_WHITE /* color used for the player */
|
2007-06-05 21:49:51 +00:00
|
|
|
#elif LCD_DEPTH>=2
|
2006-05-23 03:57:35 +00:00
|
|
|
#define CLR_RED LCD_DARKGRAY /* used to imply danger */
|
|
|
|
#define CLR_LTBLUE LCD_LIGHTGRAY /* used for frame and filling */
|
|
|
|
#define PLR_COL LCD_BLACK /* color used for the player */
|
2006-03-12 09:35:53 +00:00
|
|
|
#endif
|
|
|
|
|
2007-06-05 21:49:51 +00:00
|
|
|
#if LCD_DEPTH>=2
|
2006-03-12 09:35:53 +00:00
|
|
|
#define EMPTIED LCD_BLACK /* empty spot */
|
2006-05-23 03:57:35 +00:00
|
|
|
#define FILLED CLR_LTBLUE /* filled spot */
|
2006-03-12 09:35:53 +00:00
|
|
|
#define TRAIL CLR_RED /* the red trail of the player */
|
|
|
|
#define QIX LCD_WHITE
|
2007-06-05 21:49:51 +00:00
|
|
|
#else
|
|
|
|
#define EMPTIED 0
|
|
|
|
#define FILLED 1
|
|
|
|
#define TRAIL 2
|
|
|
|
#define QIX 3
|
|
|
|
#endif
|
2006-03-12 09:35:53 +00:00
|
|
|
#define UNCHECKED 0
|
|
|
|
#define CHECKED 1
|
2007-06-05 19:52:21 +00:00
|
|
|
#define PAINTED -1
|
2006-03-12 09:35:53 +00:00
|
|
|
#define PIC_QIX 0
|
|
|
|
#define PIC_PLAYER 1
|
|
|
|
|
|
|
|
/* The time (in ms) for one iteration through the game loop - decrease this
|
|
|
|
to speed up the game - note that current_tick is (currently) only accurate
|
|
|
|
to 10ms.
|
|
|
|
*/
|
2007-06-03 22:19:56 +00:00
|
|
|
static int speed = 6; /* CYCLETIME = (11-speed)*10 ms */
|
|
|
|
static int difficulty = 75; /* Percentage of screen that needs to be filled
|
|
|
|
* in order to win the game */
|
2006-03-12 09:35:53 +00:00
|
|
|
|
|
|
|
static bool quit = false;
|
2014-04-23 21:25:05 +00:00
|
|
|
static bool _ingame = false;
|
|
|
|
|
|
|
|
#define RESUME_FILE PLUGIN_GAMES_DATA_DIR "/xobox.resume"
|
|
|
|
#define SCORE_FILE PLUGIN_GAMES_DATA_DIR "/xobox.score"
|
|
|
|
#define NUM_SCORES 5
|
|
|
|
static struct highscore highscores[NUM_SCORES];
|
2006-03-12 09:35:53 +00:00
|
|
|
|
2007-06-05 19:52:21 +00:00
|
|
|
static unsigned int board[BOARD_H][BOARD_W];
|
|
|
|
static int testboard[BOARD_H][BOARD_W];
|
2006-03-12 09:35:53 +00:00
|
|
|
|
2007-06-05 21:49:51 +00:00
|
|
|
#if CUBE_SIZE == 8
|
2006-03-12 09:35:53 +00:00
|
|
|
/*
|
2007-06-03 17:34:23 +00:00
|
|
|
00011000 0x18 - 11100111 0xe7
|
|
|
|
00111100 0x3c - 11100111 0xe7
|
|
|
|
01111110 0x7e - 11000011 0xc3
|
|
|
|
11111111 0xff - 00000000 0x00
|
|
|
|
11111111 0xff - 00000000 0x00
|
|
|
|
01111110 0x7e - 11000011 0xc3
|
|
|
|
00111100 0x3c - 11100111 0xe7
|
|
|
|
00011000 0x18 - 11100111 0xe7
|
2006-03-12 09:35:53 +00:00
|
|
|
*/
|
|
|
|
const unsigned char pics[2][8] = {
|
2007-06-03 17:34:23 +00:00
|
|
|
{0x18, 0x3c, 0x7e, 0xff, 0xff, 0x7e, 0x3c, 0x18}, /* Alien (QIX) */
|
|
|
|
{0xe7, 0xe7, 0xc3, 0x00, 0x00, 0xc3, 0xe7, 0xe7} /* Player (XONIX) */
|
2006-03-12 09:35:53 +00:00
|
|
|
};
|
2007-06-05 21:49:51 +00:00
|
|
|
#elif CUBE_SIZE == 4
|
|
|
|
/*
|
2007-06-05 22:37:49 +00:00
|
|
|
0110 0x6 - 1001 0x9
|
|
|
|
1111 0xf - 0110 0x6
|
|
|
|
1111 0xf - 0110 0x6
|
|
|
|
0110 0x6 - 1001 0x9
|
2007-06-05 21:49:51 +00:00
|
|
|
*/
|
|
|
|
const unsigned char pics[2][4] = {
|
2007-06-05 22:37:49 +00:00
|
|
|
{0x6, 0xf, 0xf, 0x6}, /* Alien (QIX) */
|
|
|
|
{0x9, 0x6, 0x6, 0x9} /* Player (XONIX) */
|
2007-06-05 21:49:51 +00:00
|
|
|
};
|
|
|
|
#else
|
|
|
|
#error Incorrect CUBE_SIZE value.
|
|
|
|
#endif
|
2006-03-12 09:35:53 +00:00
|
|
|
|
|
|
|
static struct qix
|
|
|
|
{
|
2007-06-03 17:34:23 +00:00
|
|
|
int velocity; /* velocity */
|
|
|
|
int x, y; /* position on screen */
|
|
|
|
int angle; /* angle */
|
2006-03-12 09:35:53 +00:00
|
|
|
} qixes[MAX_QIXES]; /* black_qix */
|
|
|
|
|
|
|
|
static struct splayer
|
|
|
|
{
|
2007-06-03 17:34:23 +00:00
|
|
|
int i, j; /* position on board */
|
|
|
|
int move, score, level, lives;
|
2006-03-12 09:35:53 +00:00
|
|
|
bool drawing;
|
|
|
|
bool gameover;
|
|
|
|
} player;
|
|
|
|
|
2007-06-03 17:34:23 +00:00
|
|
|
static int percentage_cache;
|
|
|
|
|
2006-03-12 09:35:53 +00:00
|
|
|
/*************************** STACK STUFF **********************/
|
|
|
|
|
|
|
|
/* the stack */
|
2007-06-06 20:48:01 +00:00
|
|
|
#define STACK_SIZE (2*BOARD_W*BOARD_H)
|
2006-03-12 09:35:53 +00:00
|
|
|
static struct pos
|
|
|
|
{
|
|
|
|
int x, y; /* position on board */
|
|
|
|
} stack[STACK_SIZE];
|
|
|
|
static int stackPointer;
|
|
|
|
|
2007-06-03 17:34:23 +00:00
|
|
|
static inline bool pop (struct pos *p)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
|
|
|
if (stackPointer > 0) {
|
|
|
|
p->x = stack[stackPointer].x;
|
|
|
|
p->y = stack[stackPointer].y;
|
|
|
|
stackPointer--;
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false; /* SE */
|
|
|
|
}
|
|
|
|
|
2007-06-03 17:34:23 +00:00
|
|
|
static inline bool push (struct pos *p)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
|
|
|
if (stackPointer < STACK_SIZE - 1) {
|
|
|
|
stackPointer++;
|
|
|
|
stack[stackPointer].x = p->x;
|
|
|
|
stack[stackPointer].y = p->y;
|
|
|
|
return true;
|
|
|
|
} else
|
|
|
|
return false; /* SOF */
|
|
|
|
}
|
|
|
|
|
2007-06-03 17:34:23 +00:00
|
|
|
static inline void emptyStack (void)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
|
|
|
stackPointer = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*********************** END OF STACK STUFF *********************/
|
|
|
|
|
|
|
|
/* calculate the new x coordinate of the ball according to angle and speed */
|
2007-06-03 17:34:23 +00:00
|
|
|
static inline int get_newx (int x, int len, int deg)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
2007-06-03 17:34:23 +00:00
|
|
|
if (deg & DIR_R)
|
|
|
|
return x + len;
|
|
|
|
else if (deg & DIR_L)
|
|
|
|
return x - len;
|
|
|
|
else if (deg & DIR_RR)
|
|
|
|
return x + len * 2;
|
|
|
|
else /* (def & DIR_LL) */
|
|
|
|
return x - len * 2;
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* calculate the new y coordinate of the ball according to angle and speed */
|
2007-06-03 17:34:23 +00:00
|
|
|
static inline int get_newy (int y, int len, int deg)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
2007-06-03 17:34:23 +00:00
|
|
|
if (deg & DIR_D)
|
|
|
|
return y + len;
|
|
|
|
else if (deg & DIR_U)
|
|
|
|
return y - len;
|
|
|
|
else if (deg & DIR_DD)
|
|
|
|
return y + len * 2;
|
|
|
|
else /* (deg & DIR_UU) */
|
|
|
|
return y - len * 2;
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* make random function get it's value from the device ticker */
|
|
|
|
static inline void randomize (void)
|
|
|
|
{
|
|
|
|
rb->srand (*rb->current_tick);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* get a random number between 0 and range-1 */
|
|
|
|
static int t_rand (int range)
|
|
|
|
{
|
|
|
|
return rb->rand () % range;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* initializes the test help board */
|
|
|
|
static void init_testboard (void)
|
|
|
|
{
|
2007-06-03 17:34:23 +00:00
|
|
|
int j; /* testboard */
|
2006-03-12 09:35:53 +00:00
|
|
|
for (j = 0; j < BOARD_H; j++)
|
2007-06-03 17:34:23 +00:00
|
|
|
/* UNCHEKED == (int)0 */
|
|
|
|
rb->memset( testboard[j], 0, BOARD_W * sizeof( int ) );
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* initializes the game board on with the player,qix's and black qix */
|
|
|
|
static void init_board (void)
|
|
|
|
{
|
|
|
|
int i, j;
|
|
|
|
for (j = 0; j < BOARD_H; j++)
|
|
|
|
for (i = 0; i < BOARD_W; i++) { /* make a nice cyan frame */
|
2006-09-17 15:07:11 +00:00
|
|
|
if ((i == 0) || (j <= 1) || (i == BOARD_W - 1)
|
|
|
|
|| (j >= BOARD_H - 2))
|
2006-03-12 09:35:53 +00:00
|
|
|
board[j][i] = FILLED;
|
|
|
|
else
|
|
|
|
board[j][i] = EMPTIED;
|
|
|
|
}
|
2007-06-06 20:48:01 +00:00
|
|
|
|
2006-03-12 09:35:53 +00:00
|
|
|
/* (level+2) is the number of qixes */
|
|
|
|
for (j = 0; j < player.level + STARTING_QIXES; j++) {
|
|
|
|
qixes[j].velocity = t_rand (2) + 1; /* 1 or 2 pix-per-sec */
|
|
|
|
|
|
|
|
/* not on frame */
|
2007-06-06 20:48:01 +00:00
|
|
|
qixes[j].x = CUBE_SIZE*2 + 2*t_rand (((BOARD_W-4)*CUBE_SIZE)/2);
|
|
|
|
qixes[j].y = CUBE_SIZE*2 + 2*t_rand (((BOARD_H-4)*CUBE_SIZE)/2);
|
2006-03-12 09:35:53 +00:00
|
|
|
|
2007-06-05 19:52:21 +00:00
|
|
|
const int angle_table[] = {
|
|
|
|
MOVE_UUR, MOVE_UR, MOVE_URR, MOVE_DRR, MOVE_DR, MOVE_DDR,
|
|
|
|
MOVE_UUL, MOVE_UL, MOVE_ULL, MOVE_DLL, MOVE_DL, MOVE_DDL };
|
|
|
|
qixes[j].angle = angle_table[t_rand (12)];
|
2007-06-06 20:48:01 +00:00
|
|
|
#if CUBE_SIZE == 4
|
|
|
|
/* Work arround a nasty bug. FIXME */
|
|
|
|
if( qixes[j].angle & (DIR_LL|DIR_RR|DIR_UU|DIR_DD) )
|
|
|
|
qixes[j].velocity = 1;
|
|
|
|
#endif
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
/*black_qix.velocity=1;
|
|
|
|
black_qix.x=BOARD_X+(BOARD_W*CUBE_SIZE)/2-CUBE_SIZE/2;
|
|
|
|
black_qix.y=BOARD_Y+(BOARD_H*CUBE_SIZE)-CUBE_SIZE-CUBE_SIZE/2;
|
|
|
|
black_qix.angle=MOVE_UR; */
|
|
|
|
player.move = MOVE_NO;
|
|
|
|
player.drawing = false;
|
|
|
|
player.i = BOARD_W / 2;
|
|
|
|
player.j = 1;
|
2007-06-03 17:34:23 +00:00
|
|
|
|
|
|
|
percentage_cache = 0;
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* calculates the percentage of the screen filling */
|
|
|
|
static int percentage (void)
|
|
|
|
{
|
|
|
|
int i, j, filled = 0;
|
|
|
|
for (j = 2; j < BOARD_H - 2; j++)
|
|
|
|
for (i = 1; i < BOARD_W - 1; i++)
|
|
|
|
if (board[j][i] == FILLED)
|
|
|
|
filled++;
|
2007-06-03 21:09:32 +00:00
|
|
|
return (filled * 100) / ((BOARD_W - 2) * (BOARD_H - 4));
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* draw the board on with all the game figures */
|
|
|
|
static void refresh_board (void)
|
|
|
|
{
|
|
|
|
int i, j;
|
2010-08-28 21:46:45 +00:00
|
|
|
int x;
|
2006-03-12 09:35:53 +00:00
|
|
|
|
2007-06-05 21:49:51 +00:00
|
|
|
#if LCD_DEPTH>=2
|
2006-03-12 09:35:53 +00:00
|
|
|
rb->lcd_set_background (LCD_BLACK);
|
2007-06-05 21:49:51 +00:00
|
|
|
#endif
|
2009-02-09 23:21:35 +00:00
|
|
|
rb->lcd_clear_display ();
|
2006-03-12 09:35:53 +00:00
|
|
|
for (j = 0; j < BOARD_H; j++)
|
2006-09-17 15:07:11 +00:00
|
|
|
{
|
|
|
|
unsigned last_color = board[j][0];
|
|
|
|
int last_i = 0;
|
|
|
|
for (i = 1; i < BOARD_W; i++) {
|
|
|
|
if( last_color != board[j][i] )
|
|
|
|
{
|
2007-06-05 21:49:51 +00:00
|
|
|
#if LCD_DEPTH>=2
|
2006-09-17 15:07:11 +00:00
|
|
|
rb->lcd_set_foreground (last_color);
|
2007-06-05 21:49:51 +00:00
|
|
|
#else
|
|
|
|
if (last_color != EMPTIED)
|
|
|
|
#endif
|
2006-09-17 15:07:11 +00:00
|
|
|
rb->lcd_fillrect (BOARD_X + CUBE_SIZE * (last_i),
|
|
|
|
BOARD_Y + CUBE_SIZE * j,
|
|
|
|
CUBE_SIZE * (i - last_i), CUBE_SIZE );
|
|
|
|
last_color = board[j][i];
|
|
|
|
last_i = i;
|
|
|
|
}
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
2007-06-05 21:49:51 +00:00
|
|
|
#if LCD_DEPTH>=2
|
2006-09-17 15:07:11 +00:00
|
|
|
rb->lcd_set_foreground (last_color);
|
2007-06-05 21:49:51 +00:00
|
|
|
#else
|
|
|
|
if (last_color != EMPTIED)
|
|
|
|
#endif
|
2006-09-17 15:07:11 +00:00
|
|
|
rb->lcd_fillrect (BOARD_X + CUBE_SIZE * (last_i),
|
|
|
|
BOARD_Y + CUBE_SIZE * j,
|
|
|
|
CUBE_SIZE * (i - last_i), CUBE_SIZE);
|
|
|
|
}
|
2007-06-03 21:09:32 +00:00
|
|
|
|
2007-06-05 21:49:51 +00:00
|
|
|
#if LCD_DEPTH>=2
|
2006-03-12 09:35:53 +00:00
|
|
|
rb->lcd_set_foreground (LCD_BLACK);
|
2006-05-23 03:57:35 +00:00
|
|
|
rb->lcd_set_background (CLR_LTBLUE);
|
2007-06-05 21:49:51 +00:00
|
|
|
#else
|
|
|
|
rb->lcd_set_drawmode (DRMODE_COMPLEMENT);
|
|
|
|
#endif
|
2010-08-28 21:46:45 +00:00
|
|
|
rb->lcd_putsxyf (BOARD_X, BOARD_Y, "Level %d", player.level + 1);
|
|
|
|
rb->lcd_putsxyf (BOARD_X + CUBE_SIZE * BOARD_W - 24, BOARD_Y, "%d%%",
|
|
|
|
percentage_cache);
|
|
|
|
rb->lcd_putsxyf (BOARD_X, BOARD_Y + CUBE_SIZE * BOARD_H - 8, "Score: %d",
|
|
|
|
player.score);
|
2007-06-05 21:49:51 +00:00
|
|
|
#if LCD_DEPTH>=2
|
2010-08-28 21:46:45 +00:00
|
|
|
x = BOARD_X + CUBE_SIZE * BOARD_W - 60;
|
2007-06-05 21:49:51 +00:00
|
|
|
#else
|
2010-08-28 21:46:45 +00:00
|
|
|
x = BOARD_X + CUBE_SIZE * BOARD_W - 40;
|
2007-06-05 21:49:51 +00:00
|
|
|
#endif
|
2010-08-28 21:46:45 +00:00
|
|
|
rb->lcd_putsxyf (x, BOARD_Y + CUBE_SIZE * BOARD_H - 8,
|
|
|
|
(player.lives != 1) ? "%d Lives" : "%d Life", player.lives);
|
2006-03-12 09:35:53 +00:00
|
|
|
|
2007-06-05 21:49:51 +00:00
|
|
|
#if LCD_DEPTH>=2
|
2006-03-22 17:47:31 +00:00
|
|
|
rb->lcd_set_foreground (PLR_COL);
|
2006-03-12 09:35:53 +00:00
|
|
|
rb->lcd_set_background (board[player.j][player.i]);
|
2007-06-05 21:49:51 +00:00
|
|
|
#endif
|
2006-03-12 09:35:53 +00:00
|
|
|
rb->lcd_mono_bitmap (pics[PIC_PLAYER], player.i * CUBE_SIZE + BOARD_X,
|
|
|
|
player.j * CUBE_SIZE + BOARD_Y, CUBE_SIZE, CUBE_SIZE);
|
2007-06-03 21:09:32 +00:00
|
|
|
|
2007-06-05 21:49:51 +00:00
|
|
|
#if LCD_DEPTH>=2
|
2006-03-12 09:35:53 +00:00
|
|
|
rb->lcd_set_background (EMPTIED);
|
2006-03-22 17:47:31 +00:00
|
|
|
rb->lcd_set_foreground (LCD_WHITE);
|
2007-06-05 21:49:51 +00:00
|
|
|
rb->lcd_set_drawmode (DRMODE_FG);
|
|
|
|
#else
|
2007-06-06 20:55:42 +00:00
|
|
|
rb->lcd_set_drawmode (DRMODE_FG);
|
2007-06-05 21:49:51 +00:00
|
|
|
#endif
|
2006-03-12 09:35:53 +00:00
|
|
|
for (j = 0; j < player.level + STARTING_QIXES; j++)
|
|
|
|
rb->lcd_mono_bitmap (pics[PIC_QIX], qixes[j].x + BOARD_X,
|
|
|
|
qixes[j].y + BOARD_Y, CUBE_SIZE, CUBE_SIZE);
|
2007-06-05 21:49:51 +00:00
|
|
|
#if LCD_DEPTH>=2
|
2006-03-12 09:35:53 +00:00
|
|
|
rb->lcd_set_foreground (LCD_BLACK);
|
2007-06-05 21:49:51 +00:00
|
|
|
#endif
|
|
|
|
rb->lcd_set_drawmode (DRMODE_SOLID);
|
2006-03-12 09:35:53 +00:00
|
|
|
|
|
|
|
rb->lcd_update ();
|
|
|
|
}
|
|
|
|
|
2007-06-05 19:52:21 +00:00
|
|
|
static inline int infested_area (int i, int j, int v)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
2007-06-03 17:34:23 +00:00
|
|
|
struct pos p;
|
2006-03-12 09:35:53 +00:00
|
|
|
p.x = i;
|
|
|
|
p.y = j;
|
|
|
|
emptyStack ();
|
|
|
|
if (!push (&p))
|
|
|
|
return -1;
|
2006-03-17 13:38:45 +00:00
|
|
|
while (pop (&p)) {
|
2007-06-05 19:52:21 +00:00
|
|
|
if (testboard[p.y][p.x] == v) continue;
|
|
|
|
if (testboard[p.y][p.x] > UNCHECKED)
|
|
|
|
return 1; /* This area was previously flagged as infested */
|
|
|
|
testboard[p.y][p.x] = v;
|
|
|
|
if (board[p.y][p.x] == QIX)
|
|
|
|
return 1; /* Infested area */
|
2007-06-03 17:34:23 +00:00
|
|
|
{
|
|
|
|
struct pos p1 = { p.x+1, p.y };
|
2007-06-05 19:52:21 +00:00
|
|
|
if ((p1.x < BOARD_W)
|
|
|
|
&& (board[p1.y][p1.x] != FILLED)
|
|
|
|
&& (!push (&p1)))
|
|
|
|
return -1;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
|
|
|
{
|
|
|
|
struct pos p1 = { p.x-1, p.y };
|
2007-06-05 19:52:21 +00:00
|
|
|
if ((p1.x >= 0)
|
|
|
|
&& (board[p1.y][p1.x] != FILLED)
|
|
|
|
&& (!push (&p1)))
|
|
|
|
return -1;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
|
|
|
{
|
|
|
|
struct pos p1 = { p.x, p.y+1 };
|
2007-06-05 19:52:21 +00:00
|
|
|
if ((p1.y < BOARD_H)
|
|
|
|
&& (board[p1.y][p1.x] != FILLED)
|
|
|
|
&& (!push (&p1)))
|
|
|
|
return -1;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
|
|
|
{
|
|
|
|
struct pos p1 = { p.x, p.y-1 };
|
2007-06-05 19:52:21 +00:00
|
|
|
if ((p1.y >= 0)
|
|
|
|
&& (board[p1.y][p1.x] != FILLED)
|
|
|
|
&& (!push (&p1)))
|
|
|
|
return -1;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
2007-06-03 17:48:25 +00:00
|
|
|
return 0;
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline int fill_area (int i, int j)
|
|
|
|
{
|
2007-06-03 17:34:23 +00:00
|
|
|
struct pos p;
|
2006-03-12 09:35:53 +00:00
|
|
|
p.x = i;
|
|
|
|
p.y = j;
|
2007-06-05 19:52:21 +00:00
|
|
|
int v = testboard[p.y][p.x];
|
2006-03-12 09:35:53 +00:00
|
|
|
emptyStack ();
|
|
|
|
if (!push (&p))
|
|
|
|
return -1;
|
|
|
|
while (pop (&p)) {
|
|
|
|
board[p.y][p.x] = FILLED;
|
2007-06-05 19:52:21 +00:00
|
|
|
testboard[p.y][p.x] = PAINTED;
|
2007-06-03 17:34:23 +00:00
|
|
|
{
|
|
|
|
struct pos p1 = { p.x+1, p.y };
|
2007-06-05 19:52:21 +00:00
|
|
|
if ((p1.x < BOARD_W)
|
|
|
|
&& (testboard[p1.y][p1.x] == v)
|
|
|
|
&& (!push (&p1)))
|
|
|
|
return -1;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
|
|
|
{
|
|
|
|
struct pos p1 = { p.x-1, p.y };
|
2007-06-05 19:52:21 +00:00
|
|
|
if ((p1.x >= 0)
|
|
|
|
&& (testboard[p1.y][p1.x] == v)
|
|
|
|
&& (!push (&p1)))
|
|
|
|
return -1;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
|
|
|
{
|
|
|
|
struct pos p1 = { p.x, p.y+1 };
|
2007-06-05 19:52:21 +00:00
|
|
|
if ((p1.y < BOARD_H)
|
|
|
|
&& (testboard[p1.y][p1.x] == v)
|
|
|
|
&& (!push (&p1)))
|
|
|
|
return -1;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
|
|
|
{
|
|
|
|
struct pos p1 = { p.x, p.y-1 };
|
2007-06-05 19:52:21 +00:00
|
|
|
if ((p1.y >= 0)
|
|
|
|
&& (testboard[p1.y][p1.x] == v)
|
|
|
|
&& (!push (&p1)))
|
|
|
|
return -1;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
2007-06-05 19:52:21 +00:00
|
|
|
return 0;
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* take care of stuff after xonix has landed on a filled spot */
|
2006-03-17 13:38:45 +00:00
|
|
|
static void complete_trail (int fill)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
|
|
|
int i, j, ret;
|
2007-06-03 17:34:23 +00:00
|
|
|
for (j = 0; j < BOARD_H; j++) {
|
2006-03-17 13:38:45 +00:00
|
|
|
for (i = 0; i < BOARD_W; i++) {
|
|
|
|
if (board[j][i] == TRAIL) {
|
|
|
|
if (fill)
|
|
|
|
board[j][i] = FILLED;
|
|
|
|
else
|
|
|
|
board[j][i] = EMPTIED;
|
|
|
|
}
|
|
|
|
}
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
2006-03-17 13:38:45 +00:00
|
|
|
|
|
|
|
if (fill) {
|
2007-06-05 19:52:21 +00:00
|
|
|
int v = CHECKED;
|
2006-03-17 13:38:45 +00:00
|
|
|
for (i = 0; i < player.level + STARTING_QIXES; i++) /* add qixes to board */
|
2007-06-05 19:52:21 +00:00
|
|
|
board[pos(qixes[i].y - BOARD_Y)]
|
|
|
|
[pos(qixes[i].x - BOARD_X)] = QIX;
|
2006-05-23 03:33:02 +00:00
|
|
|
|
2007-06-03 17:34:23 +00:00
|
|
|
init_testboard();
|
2007-06-05 19:52:21 +00:00
|
|
|
for (j = 1; j < BOARD_H - 1; j++) {
|
|
|
|
for (i = 0; i < BOARD_W - 0; i++) {
|
|
|
|
if (board[j][i] != FILLED) {
|
|
|
|
ret = infested_area (i, j, v);
|
|
|
|
if (ret < 0 || ( ret == 0 && fill_area (i, j) ) )
|
2006-03-12 09:35:53 +00:00
|
|
|
quit = true;
|
2007-06-05 19:52:21 +00:00
|
|
|
v++;
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
2007-06-05 19:52:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0; i < player.level + STARTING_QIXES; i++) /* add qixes to board */
|
|
|
|
board[pos(qixes[i].y - BOARD_Y)]
|
|
|
|
[pos(qixes[i].x - BOARD_X)] = EMPTIED;
|
2007-06-03 17:34:23 +00:00
|
|
|
percentage_cache = percentage();
|
2006-03-17 13:38:45 +00:00
|
|
|
}
|
2006-05-23 03:57:35 +00:00
|
|
|
|
|
|
|
rb->button_clear_queue();
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* returns the color the real pixel(x,y) on the lcd is pointing at */
|
2007-06-03 17:34:23 +00:00
|
|
|
static inline unsigned int getpixel (int x, int y)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
2007-06-03 17:34:23 +00:00
|
|
|
const int a = pos (x - BOARD_X), b = pos (y - BOARD_Y);
|
2006-03-12 09:35:53 +00:00
|
|
|
if ((a > 0) && (a < BOARD_W) && (b > 0) && (b < BOARD_H)) /* if inside board */
|
|
|
|
return board[b][a];
|
|
|
|
else
|
|
|
|
return FILLED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* returns the color the ball on (newx,newy) is heading at *----*
|
|
|
|
checks the four edge points of the square if 1st of all | |
|
|
|
|
are a trail (cause it's a lose life situation) and 2nd | |
|
|
|
|
if it's filled so it needs to bounce. *____*
|
|
|
|
*/
|
2007-06-03 17:34:23 +00:00
|
|
|
static inline unsigned int next_hit (int newx, int newy)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
|
|
|
if ((getpixel (newx, newy) == TRAIL)
|
|
|
|
|| (getpixel (newx, newy + CUBE_SIZE - 1) == TRAIL)
|
|
|
|
|| (getpixel (newx + CUBE_SIZE - 1, newy) == TRAIL)
|
|
|
|
|| (getpixel (newx + CUBE_SIZE - 1, newy + CUBE_SIZE - 1) == TRAIL))
|
|
|
|
return TRAIL;
|
|
|
|
else if ((getpixel (newx, newy) == FILLED)
|
|
|
|
|| (getpixel (newx, newy + CUBE_SIZE - 1) == FILLED)
|
|
|
|
|| (getpixel (newx + CUBE_SIZE - 1, newy) == FILLED)
|
|
|
|
|| (getpixel (newx + CUBE_SIZE - 1, newy + CUBE_SIZE - 1) ==
|
|
|
|
FILLED))
|
|
|
|
return FILLED;
|
|
|
|
else
|
|
|
|
return EMPTIED;
|
|
|
|
}
|
|
|
|
|
2006-03-17 13:38:45 +00:00
|
|
|
static void die (void)
|
|
|
|
{
|
|
|
|
player.lives--;
|
|
|
|
if (player.lives == 0)
|
|
|
|
player.gameover = true;
|
|
|
|
else {
|
|
|
|
refresh_board ();
|
2007-03-16 21:56:08 +00:00
|
|
|
rb->splash (HZ, "Crash!");
|
2006-03-17 13:38:45 +00:00
|
|
|
complete_trail (false);
|
|
|
|
player.move = MOVE_NO;
|
|
|
|
player.drawing = false;
|
|
|
|
player.i = BOARD_W / 2;
|
|
|
|
player.j = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-06-03 17:34:23 +00:00
|
|
|
/* returns true if the (side) of the block -***-
|
|
|
|
starting from (newx,newy) has any filled pixels * *
|
2007-06-05 19:52:21 +00:00
|
|
|
-***-
|
2007-06-03 17:34:23 +00:00
|
|
|
*/
|
|
|
|
static inline bool line_check_lt (int newx, int newy)
|
|
|
|
{
|
2007-06-06 20:48:01 +00:00
|
|
|
return getpixel (newx, newy + CUBE_SIZE/2-1) == FILLED
|
|
|
|
&& getpixel (newx, newy + CUBE_SIZE/2 ) == FILLED;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
|
|
|
static inline bool line_check_rt (int newx, int newy)
|
|
|
|
{
|
2007-06-06 20:48:01 +00:00
|
|
|
return getpixel (newx + CUBE_SIZE-1, newy + CUBE_SIZE/2-1) == FILLED
|
|
|
|
&& getpixel (newx + CUBE_SIZE-1, newy + CUBE_SIZE/2 ) == FILLED;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
|
|
|
static inline bool line_check_up (int newx, int newy)
|
|
|
|
{
|
2007-06-06 20:48:01 +00:00
|
|
|
return getpixel (newx + CUBE_SIZE/2-1, newy) == FILLED
|
|
|
|
&& getpixel (newx + CUBE_SIZE/2 , newy) == FILLED;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
|
|
|
static inline bool line_check_dn (int newx, int newy)
|
|
|
|
{
|
2007-06-06 20:48:01 +00:00
|
|
|
return getpixel (newx + CUBE_SIZE/2-1, newy + CUBE_SIZE-1) == FILLED
|
|
|
|
&& getpixel (newx + CUBE_SIZE/2 , newy + CUBE_SIZE-1) == FILLED;
|
2007-06-03 17:34:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static inline void move_qix (struct qix *q)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
2007-06-03 17:34:23 +00:00
|
|
|
int newx, newy;
|
2006-03-12 09:35:53 +00:00
|
|
|
newx = get_newx (q->x, q->velocity, q->angle);
|
|
|
|
newy = get_newy (q->y, q->velocity, q->angle);
|
2007-06-03 17:48:25 +00:00
|
|
|
switch (next_hit (newx, newy))
|
|
|
|
{
|
|
|
|
case EMPTIED:
|
|
|
|
q->x = newx;
|
|
|
|
q->y = newy;
|
|
|
|
break;
|
|
|
|
case FILLED:
|
|
|
|
{
|
|
|
|
const int a = q->angle;
|
|
|
|
q->angle =
|
|
|
|
((a&(DIR_UU|DIR_U))
|
|
|
|
? (line_check_up (newx, newy) ? ((a&(DIR_UU|DIR_U))>>4)
|
|
|
|
: (a&(DIR_UU|DIR_U)))
|
|
|
|
: 0)
|
|
|
|
|
|
|
|
|
((a&(DIR_RR|DIR_R))
|
|
|
|
? (line_check_rt (newx, newy) ? ((a&(DIR_RR|DIR_R))>>4)
|
|
|
|
: (a&(DIR_RR|DIR_R)))
|
|
|
|
: 0)
|
|
|
|
|
|
|
|
|
((a&(DIR_DD|DIR_D))
|
|
|
|
? (line_check_dn (newx, newy) ? ((a&(DIR_DD|DIR_D))<<4)
|
|
|
|
: (a&(DIR_DD|DIR_D)))
|
|
|
|
: 0)
|
|
|
|
|
|
|
|
|
((a&(DIR_LL|DIR_L))
|
|
|
|
? (line_check_lt (newx, newy) ? ((a&(DIR_LL|DIR_L))<<4)
|
|
|
|
: (a&(DIR_LL|DIR_L)))
|
|
|
|
: 0);
|
|
|
|
q->x = get_newx (q->x, q->velocity, q->angle);
|
|
|
|
q->y = get_newy (q->y, q->velocity, q->angle);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case TRAIL:
|
|
|
|
die();
|
|
|
|
break;
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* move the board forward timewise */
|
|
|
|
static inline void move_board (void)
|
|
|
|
{
|
|
|
|
int j, newi, newj;
|
|
|
|
|
|
|
|
for (j = 0; j < player.level + STARTING_QIXES; j++)
|
|
|
|
move_qix (&qixes[j]);
|
|
|
|
/* move_qix(&black_qix,true); */
|
|
|
|
if (player.move) {
|
|
|
|
newi = player.i;
|
|
|
|
newj = player.j;
|
|
|
|
switch (player.move) {
|
|
|
|
case MOVE_UP:
|
|
|
|
if (player.j > 1)
|
|
|
|
newj--;
|
|
|
|
break;
|
|
|
|
case MOVE_DN:
|
|
|
|
if (player.j < BOARD_H - 2)
|
|
|
|
newj++;
|
|
|
|
break;
|
|
|
|
case MOVE_LT:
|
|
|
|
if (player.i > 0)
|
|
|
|
newi--;
|
|
|
|
break;
|
|
|
|
case MOVE_RT:
|
|
|
|
if (player.i < BOARD_W - 1)
|
|
|
|
newi++;
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((player.drawing) && (board[newj][newi] == EMPTIED)) /* continue drawing */
|
|
|
|
board[newj][newi] = TRAIL;
|
|
|
|
else if ((player.drawing) && (board[newj][newi] == FILLED)) { /* finish drawing */
|
|
|
|
player.move = MOVE_NO; /* stop moving */
|
|
|
|
player.drawing = false;
|
2006-03-17 13:38:45 +00:00
|
|
|
complete_trail (true);
|
2006-03-12 09:35:53 +00:00
|
|
|
} else if ((board[player.j][player.i] == FILLED)
|
|
|
|
&& (board[newj][newi] == EMPTIED)) {
|
|
|
|
/* start drawing */
|
|
|
|
player.drawing = true;
|
|
|
|
board[newj][newi] = TRAIL;
|
2006-05-23 03:33:02 +00:00
|
|
|
/* if the block after next is empty and we're moving onto filled, stop */
|
|
|
|
} else if ((board[newj][newi] == FILLED)
|
|
|
|
&& (board[newj + newj-player.j][newi + newi-player.i] == EMPTIED)) {
|
|
|
|
player.move = MOVE_NO;
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
player.i = newi;
|
|
|
|
player.j = newj;
|
|
|
|
}
|
2007-06-07 22:04:27 +00:00
|
|
|
if (percentage_cache >= difficulty) { /* finished level */
|
2010-01-02 19:48:14 +00:00
|
|
|
refresh_board ();
|
2008-08-15 08:27:39 +00:00
|
|
|
rb->splashf (HZ * 2, "Level %d finished", player.level+1);
|
2007-06-03 17:48:25 +00:00
|
|
|
player.score += percentage_cache;
|
2006-03-12 09:35:53 +00:00
|
|
|
if (player.level < MAX_LEVEL)
|
|
|
|
player.level++;
|
|
|
|
init_board ();
|
|
|
|
refresh_board ();
|
2011-04-24 23:44:58 +00:00
|
|
|
rb->button_clear_queue();
|
2007-03-16 21:56:08 +00:00
|
|
|
rb->splash (HZ * 2, "Ready?");
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* init game's variables */
|
|
|
|
static void init_game (void)
|
|
|
|
{
|
|
|
|
player.level = 0;
|
|
|
|
player.score = 0;
|
|
|
|
player.lives = 3;
|
|
|
|
player.gameover = false;
|
|
|
|
player.drawing = false;
|
|
|
|
init_board ();
|
|
|
|
refresh_board ();
|
2007-03-16 21:56:08 +00:00
|
|
|
rb->splash (HZ * 2, "Ready?");
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
|
2014-04-23 21:25:05 +00:00
|
|
|
static bool load_game(void)
|
|
|
|
{
|
|
|
|
int fd = rb->open(RESUME_FILE, O_RDONLY);
|
|
|
|
|
|
|
|
if (fd < 0) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool load_success =
|
|
|
|
rb->read(fd, &player, sizeof(player)) == sizeof(player) &&
|
|
|
|
rb->read(fd, &qixes, sizeof(qixes)) == sizeof(qixes) &&
|
|
|
|
rb->read(fd, &stack, sizeof(stack)) == sizeof(stack) &&
|
|
|
|
rb->read(fd, &board, sizeof(board)) == sizeof(board) &&
|
|
|
|
rb->read(fd, &testboard, sizeof(testboard)) == sizeof(testboard) &&
|
|
|
|
rb->read(fd, &speed, sizeof(speed)) == sizeof(speed) &&
|
|
|
|
rb->read(fd, &difficulty, sizeof(difficulty)) == sizeof(difficulty) &&
|
|
|
|
rb->read(fd, &stackPointer, sizeof(stackPointer)) == sizeof(stackPointer) &&
|
|
|
|
rb->read(fd, &percentage_cache,
|
|
|
|
sizeof(percentage_cache)) == sizeof(percentage_cache);
|
|
|
|
|
|
|
|
rb->close(fd);
|
|
|
|
_ingame = load_success;
|
|
|
|
|
|
|
|
return load_success;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool save_game(void)
|
|
|
|
{
|
|
|
|
int fd = rb->open(RESUME_FILE, O_WRONLY|O_CREAT, 0666);
|
|
|
|
|
|
|
|
if (fd < 0) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool save_success =
|
|
|
|
rb->write(fd, &player, sizeof(player)) > 0 &&
|
|
|
|
rb->write(fd, &qixes, sizeof(qixes)) > 0 &&
|
|
|
|
rb->write(fd, &stack, sizeof(stack)) > 0 &&
|
|
|
|
rb->write(fd, &board, sizeof(board)) > 0 &&
|
|
|
|
rb->write(fd, &testboard, sizeof(testboard)) > 0 &&
|
|
|
|
rb->write(fd, &speed, sizeof(speed)) > 0 &&
|
|
|
|
rb->write(fd, &difficulty, sizeof(difficulty)) > 0 &&
|
|
|
|
rb->write(fd, &stackPointer, sizeof(stackPointer)) > 0 &&
|
|
|
|
rb->write(fd, &percentage_cache, sizeof(percentage_cache)) > 0;
|
|
|
|
|
|
|
|
rb->close(fd);
|
|
|
|
|
|
|
|
if (!save_success) {
|
|
|
|
rb->remove(RESUME_FILE);
|
|
|
|
}
|
|
|
|
|
|
|
|
return save_success;
|
|
|
|
}
|
|
|
|
|
2009-05-26 19:14:26 +00:00
|
|
|
/* the main menu */
|
2009-06-26 17:59:33 +00:00
|
|
|
static int xobox_menu_cb(int action, const struct menu_item_ex *this_item)
|
|
|
|
{
|
2014-04-23 21:25:05 +00:00
|
|
|
intptr_t item = (intptr_t)this_item;
|
2009-06-26 17:59:33 +00:00
|
|
|
if(action == ACTION_REQUEST_MENUITEM
|
2014-04-23 21:25:05 +00:00
|
|
|
&& !_ingame && (item == 0 || item == 6))
|
2009-06-26 17:59:33 +00:00
|
|
|
return ACTION_EXIT_MENUITEM;
|
|
|
|
return action;
|
|
|
|
}
|
|
|
|
|
2009-05-26 19:14:26 +00:00
|
|
|
static int xobox_menu(bool ingame)
|
|
|
|
{
|
|
|
|
rb->button_clear_queue();
|
2009-06-26 17:59:33 +00:00
|
|
|
|
|
|
|
int selection = 0;
|
|
|
|
MENUITEM_STRINGLIST(main_menu, "Xobox Menu", xobox_menu_cb,
|
|
|
|
"Resume Game", "Start New Game",
|
|
|
|
"Speed", "Difficulty",
|
2014-04-23 21:25:05 +00:00
|
|
|
"High Scores", "Playback Control",
|
|
|
|
"Quit Without Saving", "Quit");
|
2009-06-26 17:59:33 +00:00
|
|
|
_ingame = ingame;
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
switch (rb->do_menu(&main_menu, &selection, NULL, false)) {
|
|
|
|
case 0:
|
2014-04-23 21:25:05 +00:00
|
|
|
rb->remove(RESUME_FILE);
|
|
|
|
refresh_board();
|
|
|
|
rb->splash (HZ*2, "Ready?");
|
2009-06-26 17:59:33 +00:00
|
|
|
return 0;
|
|
|
|
case 1:
|
|
|
|
init_game ();
|
|
|
|
return 0;
|
|
|
|
case 2:
|
|
|
|
rb->set_int ("Speed", "", UNIT_INT, &speed, NULL, 1, 1, 10, NULL);
|
|
|
|
break;
|
|
|
|
case 3:
|
|
|
|
rb->set_int ("Difficulty", "", UNIT_INT, &difficulty, NULL,
|
|
|
|
5, 50, 95, NULL);
|
|
|
|
break;
|
|
|
|
case 4:
|
2014-04-23 21:25:05 +00:00
|
|
|
highscore_show(-1, highscores, NUM_SCORES, true);
|
2009-06-26 17:59:33 +00:00
|
|
|
break;
|
|
|
|
case 5:
|
2014-04-23 21:25:05 +00:00
|
|
|
playback_control(NULL);
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
return 1;
|
|
|
|
case 7:
|
|
|
|
if (_ingame) {
|
|
|
|
rb->splash(HZ, "Saving game...");
|
|
|
|
|
|
|
|
if (!save_game()) {
|
|
|
|
rb->splash(HZ, "Failed to save game");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-26 17:59:33 +00:00
|
|
|
return 1;
|
|
|
|
case MENU_ATTACHED_USB:
|
|
|
|
return 1;
|
|
|
|
default:
|
|
|
|
break;
|
2009-05-26 19:14:26 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2006-03-12 09:35:53 +00:00
|
|
|
/* general keypad handler loop */
|
|
|
|
static int xobox_loop (void)
|
|
|
|
{
|
2009-05-26 19:14:26 +00:00
|
|
|
int button = 0;
|
2006-03-12 09:35:53 +00:00
|
|
|
bool pause = false;
|
|
|
|
int end;
|
|
|
|
|
2014-04-23 21:25:05 +00:00
|
|
|
if (xobox_menu(_ingame)) {
|
2009-05-26 19:14:26 +00:00
|
|
|
return PLUGIN_OK;
|
|
|
|
}
|
|
|
|
|
2006-03-12 09:35:53 +00:00
|
|
|
while (!quit) {
|
2007-06-03 22:19:56 +00:00
|
|
|
end = *rb->current_tick + ((11-speed)*HZ)/100;
|
2006-07-30 03:10:09 +00:00
|
|
|
|
|
|
|
#ifdef HAS_BUTTON_HOLD
|
|
|
|
if (rb->button_hold()) {
|
2009-06-26 17:14:48 +00:00
|
|
|
pause = true;
|
|
|
|
rb->splash (HZ, "Paused");
|
2006-07-30 03:10:09 +00:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
2008-05-26 06:55:51 +00:00
|
|
|
button = rb->button_get_w_tmo (1);
|
2006-03-12 09:35:53 +00:00
|
|
|
switch (button) {
|
|
|
|
case UP:
|
2006-05-23 03:57:35 +00:00
|
|
|
case UP|BUTTON_REPEAT:
|
2006-03-12 09:35:53 +00:00
|
|
|
player.move = MOVE_UP;
|
|
|
|
break;
|
|
|
|
case DOWN:
|
2006-05-23 03:57:35 +00:00
|
|
|
case DOWN|BUTTON_REPEAT:
|
2006-03-12 09:35:53 +00:00
|
|
|
player.move = MOVE_DN;
|
|
|
|
break;
|
|
|
|
case LEFT:
|
2006-05-23 03:57:35 +00:00
|
|
|
case LEFT|BUTTON_REPEAT:
|
2006-03-12 09:35:53 +00:00
|
|
|
player.move = MOVE_LT;
|
|
|
|
break;
|
|
|
|
case RIGHT:
|
2006-05-23 03:57:35 +00:00
|
|
|
case RIGHT|BUTTON_REPEAT:
|
2006-03-12 09:35:53 +00:00
|
|
|
player.move = MOVE_RT;
|
|
|
|
break;
|
|
|
|
case PAUSE:
|
|
|
|
pause = !pause;
|
|
|
|
if (pause)
|
2007-03-16 21:56:08 +00:00
|
|
|
rb->splash (HZ, "Paused");
|
2006-03-12 09:35:53 +00:00
|
|
|
break;
|
|
|
|
case QUIT:
|
2009-06-26 17:14:48 +00:00
|
|
|
if (!pause) {
|
|
|
|
if (xobox_menu(true)) {
|
|
|
|
quit = true;
|
|
|
|
}
|
2007-03-25 17:52:56 +00:00
|
|
|
}
|
2006-03-12 09:35:53 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
if (rb->default_event_handler (button) == SYS_USB_CONNECTED)
|
|
|
|
return PLUGIN_USB_CONNECTED;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!pause) {
|
|
|
|
move_board ();
|
|
|
|
refresh_board ();
|
|
|
|
}
|
|
|
|
if (player.gameover) {
|
2007-03-16 21:56:08 +00:00
|
|
|
rb->splash (HZ, "Game Over!");
|
2014-04-23 21:25:05 +00:00
|
|
|
|
|
|
|
int pos = highscore_update(player.score, player.level, "",
|
|
|
|
highscores, NUM_SCORES);
|
|
|
|
|
|
|
|
if (pos != -1) {
|
|
|
|
if (pos == 0) {
|
|
|
|
rb->splashf(HZ, "New High Score: %d", player.score);
|
|
|
|
}
|
|
|
|
|
2014-07-11 16:38:02 +00:00
|
|
|
highscore_show(pos, highscores, NUM_SCORES, true);
|
2014-04-23 21:25:05 +00:00
|
|
|
}
|
|
|
|
|
2009-06-26 17:14:48 +00:00
|
|
|
if (xobox_menu(false)) {
|
2006-03-12 09:35:53 +00:00
|
|
|
quit = true;
|
2009-05-26 19:14:26 +00:00
|
|
|
}
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|
|
|
|
|
2009-10-18 15:50:30 +00:00
|
|
|
if (TIME_BEFORE(*rb->current_tick, end))
|
2006-03-12 09:35:53 +00:00
|
|
|
rb->sleep (end - *rb->current_tick);
|
|
|
|
else
|
|
|
|
rb->yield ();
|
|
|
|
|
|
|
|
} /* end while */
|
|
|
|
return PLUGIN_OK; /* for no warnings on compiling */
|
|
|
|
}
|
|
|
|
|
|
|
|
/* plugin main procedure */
|
2009-01-16 10:34:40 +00:00
|
|
|
enum plugin_status plugin_start (const void *parameter)
|
2006-03-12 09:35:53 +00:00
|
|
|
{
|
2006-05-23 03:33:02 +00:00
|
|
|
int ret = PLUGIN_OK;
|
2006-03-12 09:35:53 +00:00
|
|
|
|
|
|
|
(void) parameter;
|
|
|
|
|
|
|
|
rb->lcd_setfont (FONT_SYSFIXED);
|
2007-06-05 21:49:51 +00:00
|
|
|
#if LCD_DEPTH>=2
|
2006-11-15 06:14:27 +00:00
|
|
|
rb->lcd_set_backdrop(NULL);
|
2007-06-05 21:49:51 +00:00
|
|
|
#endif
|
2006-03-12 09:35:53 +00:00
|
|
|
|
2007-08-15 12:42:09 +00:00
|
|
|
/* Turn off backlight timeout */
|
2011-01-24 12:29:16 +00:00
|
|
|
backlight_ignore_timeout();
|
2007-06-03 17:34:23 +00:00
|
|
|
|
2014-04-23 21:25:05 +00:00
|
|
|
highscore_load(SCORE_FILE, highscores, NUM_SCORES);
|
|
|
|
|
|
|
|
if (!load_game()) {
|
|
|
|
rb->splash(HZ, "Failed to load saved game");
|
|
|
|
}
|
|
|
|
|
2006-03-12 09:35:53 +00:00
|
|
|
randomize ();
|
2009-05-26 19:14:26 +00:00
|
|
|
ret = xobox_loop ();
|
2006-03-12 09:35:53 +00:00
|
|
|
|
2007-08-15 12:42:09 +00:00
|
|
|
/* Turn on backlight timeout (revert to settings) */
|
2011-01-24 12:29:16 +00:00
|
|
|
backlight_use_settings();
|
2006-03-12 09:35:53 +00:00
|
|
|
rb->lcd_setfont (FONT_UI);
|
|
|
|
|
2014-04-23 21:25:05 +00:00
|
|
|
highscore_save(SCORE_FILE, highscores, NUM_SCORES);
|
|
|
|
|
2006-03-16 08:20:57 +00:00
|
|
|
return ret;
|
2006-03-12 09:35:53 +00:00
|
|
|
}
|