summaryrefslogtreecommitdiff
path: root/apps/plugins/xrick/system
diff options
context:
space:
mode:
authorSebastian Leonhardt <sebastian.leonhardt@web.de>2016-01-08 01:05:36 +0100
committerFranklin Wei <frankhwei536@gmail.com>2016-06-13 22:49:35 -0400
commitb33d4e9ae51f7b5fcd4add3f9e7a6fb966f67d76 (patch)
tree1226f0ab0c06d71b7f5a336dcb317f456bd68551 /apps/plugins/xrick/system
parent9a6700d52e8dfb2e93623e7143204ae34f798bbf (diff)
downloadrockbox-b33d4e9ae51f7b5fcd4add3f9e7a6fb966f67d76.zip
rockbox-b33d4e9ae51f7b5fcd4add3f9e7a6fb966f67d76.tar.gz
rockbox-b33d4e9ae51f7b5fcd4add3f9e7a6fb966f67d76.tar.bz2
rockbox-b33d4e9ae51f7b5fcd4add3f9e7a6fb966f67d76.tar.xz
added xrick game
original xrick code by 'BigOrno' at: http://www.bigorno.net/xrick/ Rockbox port, plus bugfixes at: https://github.com/pierluigi-vicinanza/xrick Change-Id: Id83928bc2539901b0221692f65cbca41389c58e7
Diffstat (limited to 'apps/plugins/xrick/system')
-rw-r--r--apps/plugins/xrick/system/basic_funcs.c35
-rw-r--r--apps/plugins/xrick/system/basic_funcs.h141
-rw-r--r--apps/plugins/xrick/system/basic_types.h48
-rw-r--r--apps/plugins/xrick/system/main_rockbox.c43
-rw-r--r--apps/plugins/xrick/system/miniz_config.h38
-rw-r--r--apps/plugins/xrick/system/rockboxcodes.h103
-rw-r--r--apps/plugins/xrick/system/sysarg_rockbox.c49
-rwxr-xr-xapps/plugins/xrick/system/sysevt_rockbox.c156
-rw-r--r--apps/plugins/xrick/system/sysfile_rockbox.c122
-rw-r--r--apps/plugins/xrick/system/sysmem_rockbox.c156
-rw-r--r--apps/plugins/xrick/system/sysmenu_rockbox.c193
-rw-r--r--apps/plugins/xrick/system/sysmenu_rockbox.h32
-rw-r--r--apps/plugins/xrick/system/syssnd_rockbox.c483
-rw-r--r--apps/plugins/xrick/system/syssnd_rockbox.h48
-rw-r--r--apps/plugins/xrick/system/system.h180
-rw-r--r--apps/plugins/xrick/system/system_rockbox.c262
-rw-r--r--apps/plugins/xrick/system/sysvid_rockbox.c395
17 files changed, 2484 insertions, 0 deletions
diff --git a/apps/plugins/xrick/system/basic_funcs.c b/apps/plugins/xrick/system/basic_funcs.c
new file mode 100644
index 0000000..81fdb78
--- /dev/null
+++ b/apps/plugins/xrick/system/basic_funcs.c
@@ -0,0 +1,35 @@
+/*
+ * xrick/system/basic_funcs.c
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza. All rights reserved.
+ *
+ * The use and distribution terms for this software are contained in the file
+ * named README, which can be found in the root of this distribution. By
+ * using this software in any fashion, you are agreeing to be bound by the
+ * terms of this license.
+ *
+ * You must not remove this notice, or any other, from this software.
+ */
+
+#include "xrick/system/basic_funcs.h"
+
+#ifdef USE_DEFAULT_ENDIANNESS_FUNCTIONS
+
+extern inline uint16_t swap16(uint16_t x);
+extern inline uint32_t swap32(uint32_t x);
+
+extern inline uint16_t htobe16(uint16_t host);
+extern inline uint16_t htole16(uint16_t host);
+extern inline uint16_t betoh16(uint16_t big_endian);
+extern inline uint16_t letoh16(uint16_t little_endian);
+
+extern inline uint32_t htobe32(uint32_t host);
+extern inline uint32_t htole32(uint32_t host);
+extern inline uint32_t betoh32(uint32_t big_endian);
+extern inline uint32_t letoh32(uint32_t little_endian);
+
+#endif /* USE_DEFAULT_ENDIANNESS_FUNCTIONS */
+
+/* eof */
+
+
diff --git a/apps/plugins/xrick/system/basic_funcs.h b/apps/plugins/xrick/system/basic_funcs.h
new file mode 100644
index 0000000..1ac5c58
--- /dev/null
+++ b/apps/plugins/xrick/system/basic_funcs.h
@@ -0,0 +1,141 @@
+/*
+ * xrick/system/basic_funcs.h
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza. All rights reserved.
+ *
+ * The use and distribution terms for this software are contained in the file
+ * named README, which can be found in the root of this distribution. By
+ * using this software in any fashion, you are agreeing to be bound by the
+ * terms of this license.
+ *
+ * You must not remove this notice, or any other, from this software.
+ */
+
+#ifndef _BASIC_FUNCS_H
+#define _BASIC_FUNCS_H
+
+#include "xrick/system/basic_types.h"
+#include "xrick/system/system.h"
+
+#ifdef __WIN32__
+/* Windows is little endian only */
+# define __ORDER_LITTLE_ENDIAN__ 1234
+# define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+# define USE_DEFAULT_ENDIANNESS_FUNCTIONS
+# include <stdlib.h> /* _byteswap_XXX */
+
+#elif defined(ROCKBOX)
+/* Rockbox*/
+# include "plugin.h"
+# define __ORDER_LITTLE_ENDIAN__ 1234
+# define __ORDER_BIG_ENDIAN__ 4321
+# ifdef ROCKBOX_BIG_ENDIAN
+# define __BYTE_ORDER__ __ORDER_BIG_ENDIAN__
+# else
+# define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+# endif
+
+#elif (defined(__FreeBSD__) && __FreeBSD_version >= 470000) || defined(__OpenBSD__) || defined(__NetBSD__)
+/* *BSD */
+# include <sys/endian.h>
+# define __ORDER_BIG_ENDIAN__ BIG_ENDIAN
+# define __ORDER_LITTLE_ENDIAN__ LITTLE_ENDIAN
+# define __BYTE_ORDER__ BYTE_ORDER
+
+#elif (defined(BSD) && (BSD >= 199103)) || defined(__MacOSX__)
+/* more BSD */
+# include <machine/endian.h>
+# define __ORDER_BIG_ENDIAN__ BIG_ENDIAN
+# define __ORDER_LITTLE_ENDIAN__ LITTLE_ENDIAN
+# define __BYTE_ORDER__ BYTE_ORDER
+
+#elif defined(__linux__) /*|| defined (__BEOS__)*/
+/* Linux, BeOS */
+# include <endian.h>
+# define betoh16(x) be16toh(x)
+# define letoh16(x) le16toh(x)
+# define betoh32(x) be32toh(x)
+# define letoh32(x) le32toh(x)
+
+#else
+/* shall we just '#include <endian.h>'? */
+# define USE_DEFAULT_ENDIANNESS_FUNCTIONS
+
+#endif /* __WIN32__ */
+
+/* define default endianness */
+#ifndef __ORDER_LITTLE_ENDIAN__
+# define __ORDER_LITTLE_ENDIAN__ 1234
+#endif
+
+#ifndef __ORDER_BIG_ENDIAN__
+# define __ORDER_BIG_ENDIAN__ 4321
+#endif
+
+#ifndef __BYTE_ORDER__
+# warning "Byte order not defined on your system, assuming little endian!"
+# define __BYTE_ORDER__ __ORDER_LITTLE_ENDIAN__
+#endif
+
+/* provide default endianness functions */
+#ifdef USE_DEFAULT_ENDIANNESS_FUNCTIONS
+
+# define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
+
+inline uint32_t swap32(uint32_t x)
+{
+# ifdef _MSC_VER
+ return _byteswap_ulong(x);
+# elif (GCC_VERSION > 40300) || defined(__clang__)
+ return __builtin_bswap32(x);
+# else
+ return (x >> 24) |
+ ((x >> 8) & 0x0000FF00) |
+ ((x << 8) & 0x00FF0000) |
+ (x << 24);
+# endif /* _MSC_VER */
+}
+
+inline uint16_t swap16(uint16_t x)
+{
+# ifdef _MSC_VER
+ return _byteswap_ushort(x);
+# elif (GCC_VERSION > 40800) || defined(__clang__)
+ return __builtin_bswap16(x);
+# else
+ return (x << 8)|(x >> 8);
+# endif /* _MSC_VER */
+}
+
+# if (__BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__)
+inline uint16_t htobe16(uint16_t host) { return swap16(host); }
+inline uint16_t htole16(uint16_t host) { return host; }
+inline uint16_t betoh16(uint16_t big_endian) { return swap16(big_endian); }
+inline uint16_t letoh16(uint16_t little_endian) { return little_endian; }
+
+inline uint32_t htobe32(uint32_t host) { return swap32(host); }
+inline uint32_t htole32(uint32_t host) { return host; }
+inline uint32_t betoh32(uint32_t big_endian) { return swap32(big_endian); }
+inline uint32_t letoh32(uint32_t little_endian) { return little_endian; }
+
+# elif (__BYTE_ORDER__==__ORDER_BIG_ENDIAN__)
+inline uint16_t htobe16(uint16_t host) { return host; }
+inline uint16_t htole16(uint16_t host) { return swap16(host); }
+inline uint16_t betoh16(uint16_t big_endian) { return big_endian; }
+inline uint16_t letoh16(uint16_t little_endian) { return swap16(little_endian); }
+
+inline uint32_t htobe32(uint32_t host) { return host; }
+inline uint32_t htole32(uint32_t host) { return swap32(host); }
+inline uint32_t betoh32(uint32_t big_endian) { return big_endian; }
+inline uint32_t letoh32(uint32_t little_endian) { return swap32(little_endian); }
+
+# else
+# error "Unknown/unsupported byte order!"
+
+# endif
+
+#endif /* USE_DEFAULT_ENDIANNESS_FUNCTIONS */
+
+#endif /* ndef _BASIC_FUNCS_H */
+
+/* eof */
diff --git a/apps/plugins/xrick/system/basic_types.h b/apps/plugins/xrick/system/basic_types.h
new file mode 100644
index 0000000..e05fd47
--- /dev/null
+++ b/apps/plugins/xrick/system/basic_types.h
@@ -0,0 +1,48 @@
+/*
+ * xrick/system/basic_types.h
+ *
+ * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net).
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza.
+ * All rights reserved.
+ *
+ * The use and distribution terms for this software are contained in the file
+ * named README, which can be found in the root of this distribution. By
+ * using this software in any fashion, you are agreeing to be bound by the
+ * terms of this license.
+ *
+ * You must not remove this notice, or any other, from this software.
+ */
+
+#ifndef _BASIC_TYPES_H
+#define _BASIC_TYPES_H
+
+#ifdef _MSC_VER
+
+typedef enum { false, true } bool;
+
+#define inline __inline
+
+typedef unsigned __int8 uint8_t;
+typedef unsigned __int16 uint16_t;
+typedef unsigned __int32 uint32_t;
+typedef __int8 int8_t;
+typedef __int16 int16_t;
+typedef __int32 int32_t;
+
+#else /* ndef _MSC_VER */
+
+#include <stdbool.h>
+#include <stdint.h>
+
+#endif /* _MSC_VER */
+
+typedef uint8_t U8; /* 8 bits unsigned */
+typedef uint16_t U16; /* 16 bits unsigned */
+typedef uint32_t U32; /* 32 bits unsigned */
+typedef int8_t S8; /* 8 bits signed */
+typedef int16_t S16; /* 16 bits signed */
+typedef int32_t S32; /* 32 bits signed */
+
+#endif /* ndef _BASIC_TYPES_H */
+
+/* eof */
diff --git a/apps/plugins/xrick/system/main_rockbox.c b/apps/plugins/xrick/system/main_rockbox.c
new file mode 100644
index 0000000..e273e1d
--- /dev/null
+++ b/apps/plugins/xrick/system/main_rockbox.c
@@ -0,0 +1,43 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "xrick/system/system.h"
+#include "xrick/game.h"
+
+#include "plugin.h"
+
+/* Plug-in entry point */
+enum plugin_status plugin_start(const void* parameter)
+{
+ char *filename = (char*)parameter;
+ bool success = sys_init(1, &filename);
+ if (success)
+ {
+ game_run();
+ }
+ sys_shutdown();
+ return (success? PLUGIN_OK : PLUGIN_ERROR);
+}
+
+/* eof */
diff --git a/apps/plugins/xrick/system/miniz_config.h b/apps/plugins/xrick/system/miniz_config.h
new file mode 100644
index 0000000..5d6a9e2
--- /dev/null
+++ b/apps/plugins/xrick/system/miniz_config.h
@@ -0,0 +1,38 @@
+/*
+ * xrick/system/miniz_config.h
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza. All rights reserved.
+ *
+ * The use and distribution terms for this software are contained in the file
+ * named README, which can be found in the root of this distribution. By
+ * using this software in any fashion, you are agreeing to be bound by the
+ * terms of this license.
+ *
+ * You must not remove this notice, or any other, from this software.
+ */
+
+#ifndef _MINIZ_CONFIG_H
+#define _MINIZ_CONFIG_H
+
+/*
+ * miniz used only for crc32 calculation
+ */
+#define MINIZ_NO_STDIO
+#define MINIZ_NO_TIME
+#define MINIZ_NO_ARCHIVE_APIS
+#define MINIZ_NO_ARCHIVE_WRITING_APIS
+#define MINIZ_NO_ZLIB_APIS
+#define MINIZ_NO_MALLOC
+#ifdef ROCKBOX
+# define MINIZ_NO_ASSERT
+# ifndef SIMULATOR
+# define MINIZ_X86_OR_X64_CPU 0
+# define MINIZ_HAS_64BIT_REGISTERS 0
+# define TINFL_USE_64BIT_BITBUF 0
+# define MINIZ_USE_UNALIGNED_LOADS_AND_STORES 0
+# endif /* ndef SIMULATOR */
+#endif
+
+#endif /* ndef _MINIZ_CONFIG_H */
+
+/* eof */
diff --git a/apps/plugins/xrick/system/rockboxcodes.h b/apps/plugins/xrick/system/rockboxcodes.h
new file mode 100644
index 0000000..44a1dc8
--- /dev/null
+++ b/apps/plugins/xrick/system/rockboxcodes.h
@@ -0,0 +1,103 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _ROCKBOXCODES_H
+#define _ROCKBOXCODES_H
+
+/* keypad mappings */
+#include "plugin.h"
+
+#if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \
+ (CONFIG_KEYPAD == IRIVER_H300_PAD)
+#define XRICK_BTN_UP BUTTON_UP | BUTTON_REC
+#define XRICK_BTN_DOWN BUTTON_DOWN | BUTTON_MODE
+#define XRICK_BTN_LEFT BUTTON_LEFT
+#define XRICK_BTN_RIGHT BUTTON_RIGHT
+#define XRICK_BTN_FIRE BUTTON_ON
+#define XRICK_BTN_PAUSE BUTTON_SELECT
+#define XRICK_BTN_MENU BUTTON_OFF
+
+#elif (CONFIG_KEYPAD == IRIVER_H10_PAD)
+#define XRICK_BTN_MENU BUTTON_POWER
+#define XRICK_BTN_FIRE BUTTON_PLAY
+#define XRICK_BTN_PAUSE BUTTON_REW
+#define XRICK_BTN_UP BUTTON_SCROLL_UP
+#define XRICK_BTN_DOWN BUTTON_SCROLL_DOWN
+#define XRICK_BTN_LEFT BUTTON_LEFT
+#define XRICK_BTN_RIGHT BUTTON_RIGHT
+
+#elif (CONFIG_KEYPAD == IPOD_4G_PAD) || \
+ (CONFIG_KEYPAD == IPOD_3G_PAD) || \
+ (CONFIG_KEYPAD == IPOD_1G2G_PAD)
+#define XRICK_BTN_UP BUTTON_MENU
+#define XRICK_BTN_DOWN BUTTON_PLAY
+#define XRICK_BTN_LEFT BUTTON_LEFT
+#define XRICK_BTN_RIGHT BUTTON_RIGHT
+#define XRICK_BTN_FIRE BUTTON_SELECT
+#define XRICK_BTN_PAUSE BUTTON_SCROLL_BACK
+#define XRICK_BTN_MENU BUTTON_SCROLL_FWD
+
+#elif (CONFIG_KEYPAD == SANSA_FUZEPLUS_PAD)
+#define XRICK_BTN_UP BUTTON_UP
+#define XRICK_BTN_UPLEFT BUTTON_BACK
+#define XRICK_BTN_UPRIGHT BUTTON_PLAYPAUSE
+#define XRICK_BTN_DOWN BUTTON_DOWN
+#define XRICK_BTN_DOWNLEFT BUTTON_BOTTOMLEFT
+#define XRICK_BTN_DOWNRIGHT BUTTON_BOTTOMRIGHT
+#define XRICK_BTN_LEFT BUTTON_LEFT
+#define XRICK_BTN_RIGHT BUTTON_RIGHT
+#define XRICK_BTN_FIRE BUTTON_VOL_DOWN
+#define XRICK_BTN_PAUSE BUTTON_VOL_UP
+#define XRICK_BTN_MENU BUTTON_POWER
+
+#elif (CONFIG_KEYPAD == SAMSUNG_YH920_PAD)
+#define XRICK_BTN_UP BUTTON_UP
+#define XRICK_BTN_DOWN BUTTON_DOWN
+#define XRICK_BTN_LEFT BUTTON_LEFT
+#define XRICK_BTN_RIGHT BUTTON_RIGHT
+#define XRICK_BTN_FIRE BUTTON_PLAY
+#define XRICK_BTN_PAUSE BUTTON_FFWD
+#define XRICK_BTN_MENU BUTTON_REW
+
+#elif (CONFIG_KEYPAD == SAMSUNG_YH820_PAD)
+#define XRICK_BTN_UP BUTTON_UP
+#define XRICK_BTN_DOWN BUTTON_DOWN
+#define XRICK_BTN_LEFT BUTTON_LEFT
+#define XRICK_BTN_RIGHT BUTTON_RIGHT
+#define XRICK_BTN_FIRE BUTTON_PLAY
+#define XRICK_BTN_PAUSE BUTTON_FFWD
+#define XRICK_BTN_MENU BUTTON_REW
+
+/* place other keypad mappings here
+#elif CONFIG_KEYPAD ==...
+#define XRICK_BTN...
+*/
+
+#else
+#error Unsupported keypad
+#endif
+
+#endif /* ndef _ROCKBOXCODES_H */
+
+/* eof */
diff --git a/apps/plugins/xrick/system/sysarg_rockbox.c b/apps/plugins/xrick/system/sysarg_rockbox.c
new file mode 100644
index 0000000..fa502ff
--- /dev/null
+++ b/apps/plugins/xrick/system/sysarg_rockbox.c
@@ -0,0 +1,49 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "xrick/system/system.h"
+
+/*
+ * globals
+ */
+int sysarg_args_period = 0; /* time between each frame, in milliseconds. The default is 40. */
+int sysarg_args_map = 0;
+int sysarg_args_submap = 0;
+bool sysarg_args_nosound = false;
+const char *sysarg_args_data = NULL;
+
+/*
+ * Read and process arguments
+ */
+bool sysarg_init(int argc/*unused*/, char **argv)
+{
+ (void)argc;
+
+ /* note: "*argv" is truly a "const *" */
+ sysarg_args_data = *argv;
+
+ return true;
+}
+
+/* eof */
diff --git a/apps/plugins/xrick/system/sysevt_rockbox.c b/apps/plugins/xrick/system/sysevt_rockbox.c
new file mode 100755
index 0000000..f531471
--- /dev/null
+++ b/apps/plugins/xrick/system/sysevt_rockbox.c
@@ -0,0 +1,156 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "xrick/system/system.h"
+
+#include "xrick/config.h"
+#include "xrick/control.h"
+#include "xrick/game.h"
+#include "xrick/system/sysmenu_rockbox.h"
+#include "xrick/system/rockboxcodes.h"
+
+/*
+ * Helper function to set/clear controls according to key press
+ */
+static inline void checkKey(int key, unsigned button, control_t control)
+{
+ if (key & button)
+ {
+ control_set(control);
+ }
+ else
+ {
+ control_clear(control);
+ }
+}
+
+/*
+ * Process events, if any, then return
+ */
+void sysevt_poll(void)
+{
+ static int previousKey, currentKey;
+
+ /* this is because "Restart Game" is handled via menu */
+ if (control_test(Control_END))
+ {
+ control_clear(Control_END);
+ }
+
+ for (;;)
+ {
+ /* check for USB connection */
+ if ((rb->default_event_handler(rb->button_get(false)) == SYS_USB_CONNECTED)
+#if defined(HAS_BUTTON_HOLD)
+ || rb->button_hold()
+#endif
+ )
+ {
+ sysmenu_exec();
+ }
+
+ currentKey = rb->button_status();
+ if (currentKey != previousKey)
+ {
+ break;
+ }
+ else if (game_waitevt)
+ {
+ rb->yield();
+ }
+ else /* (currentKey == previousKey) && !game_waitevt */
+ {
+ return;
+ }
+ }
+
+#ifdef XRICK_BTN_MENU
+ if (currentKey & XRICK_BTN_MENU)
+ {
+ sysmenu_exec();
+ }
+#endif
+
+#ifdef XRICK_BTN_PAUSE
+ checkKey(currentKey, XRICK_BTN_PAUSE, Control_PAUSE);
+#endif
+
+ checkKey(currentKey, XRICK_BTN_UP, Control_UP);
+
+ checkKey(currentKey, XRICK_BTN_DOWN, Control_DOWN);
+
+ checkKey(currentKey, XRICK_BTN_LEFT, Control_LEFT);
+
+ checkKey(currentKey, XRICK_BTN_RIGHT, Control_RIGHT);
+
+ checkKey(currentKey, XRICK_BTN_FIRE, Control_FIRE);
+
+#ifdef XRICK_BTN_UPLEFT
+ if (!control_test(Control_UP | Control_LEFT))
+ {
+ checkKey(currentKey, XRICK_BTN_UPLEFT, Control_UP | Control_LEFT);
+ }
+#endif /* XRICK_BTN_UPLEFT */
+
+#ifdef XRICK_BTN_UPRIGHT
+ if (!control_test(Control_UP | Control_RIGHT))
+ {
+ checkKey(currentKey, XRICK_BTN_UPRIGHT, Control_UP | Control_RIGHT);
+ }
+#endif /* XRICK_BTN_UPRIGHT */
+
+#ifdef XRICK_BTN_DOWNLEFT
+ if (!control_test(Control_DOWN | Control_LEFT))
+ {
+ checkKey(currentKey, XRICK_BTN_DOWNLEFT, Control_DOWN | Control_LEFT);
+ }
+#endif /* XRICK_BTN_DOWNLEFT */
+
+#ifdef XRICK_BTN_DOWNRIGHT
+ if (!control_test(Control_DOWN | Control_RIGHT))
+ {
+ checkKey(currentKey, XRICK_BTN_DOWNRIGHT, Control_DOWN | Control_RIGHT);
+ }
+#endif /* XRICK_BTN_DOWNRIGHT */
+
+ previousKey = currentKey;
+}
+
+/*
+ * Wait for an event, then process it and return
+ */
+void sysevt_wait(void)
+{
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(false);
+#endif
+
+ sysevt_poll(); /* sysevt_poll deals with blocking case as well */
+
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(true);
+#endif
+}
+
+/* eof */
diff --git a/apps/plugins/xrick/system/sysfile_rockbox.c b/apps/plugins/xrick/system/sysfile_rockbox.c
new file mode 100644
index 0000000..3302fa2
--- /dev/null
+++ b/apps/plugins/xrick/system/sysfile_rockbox.c
@@ -0,0 +1,122 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "xrick/system/system.h"
+
+#include "xrick/config.h"
+#include "xrick/util.h"
+
+#include "plugin.h"
+
+#define XRICK_GAME_DIR PLUGIN_GAMES_DATA_DIR "/xrick"
+
+/*
+ * Global variables
+ */
+const char *sysfile_defaultPath = XRICK_GAME_DIR;
+
+/*
+ * Local variables
+ */
+static char *rootPath = NULL;
+
+/*
+ *
+ */
+bool sysfile_setRootPath(const char *name)
+{
+ rootPath = u_strdup(name);
+ return (rootPath != NULL);
+}
+
+/*
+ *
+ */
+void sysfile_clearRootPath()
+{
+ sysmem_pop(rootPath);
+ rootPath = NULL;
+}
+
+/*
+ * Open a data file.
+ */
+file_t sysfile_open(const char *name)
+{
+ int fd;
+
+ size_t fullPathLength = rb->strlen(rootPath) + rb->strlen(name) + 2;
+ char *fullPath = sysmem_push(fullPathLength);
+ if (!fullPath)
+ {
+ return NULL;
+ }
+ rb->snprintf(fullPath, fullPathLength, "%s/%s", rootPath, name);
+ fd = rb->open(fullPath, O_RDONLY);
+ sysmem_pop(fullPath);
+
+ /*
+ * note: I've never seen zero/NULL being used as a file descriptor under Rockbox.
+ * Putting a check here in case this will ever happen (will need a fix).
+ */
+ if (fd == 0)
+ {
+ sys_error("(file) unsupported file descriptor (zero/NULL) being used");
+ }
+ if (fd < 0)
+ {
+ return NULL;
+ }
+
+ return (file_t)fd;
+}
+
+/*
+ * Read a file within a data archive.
+ */
+int sysfile_read(file_t file, void *buf, size_t size, size_t count)
+{
+ int fd = (int)file;
+ return (rb->read(fd, buf, size * count) / size);
+}
+
+/*
+ * Seek.
+ */
+int sysfile_seek(file_t file, long offset, int origin)
+{
+ int fd = (int)file;
+ return rb->lseek(fd, offset, origin);
+}
+
+/*
+ * Close a file within a data archive.
+ */
+void sysfile_close(file_t file)
+{
+ int fd = (int)file;
+ rb->close(fd);
+}
+
+/* eof */
diff --git a/apps/plugins/xrick/system/sysmem_rockbox.c b/apps/plugins/xrick/system/sysmem_rockbox.c
new file mode 100644
index 0000000..06a683a
--- /dev/null
+++ b/apps/plugins/xrick/system/sysmem_rockbox.c
@@ -0,0 +1,156 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "xrick/system/system.h"
+
+#include "xrick/debug.h"
+
+#include "plugin.h"
+
+/*
+ * Local variables
+ */
+enum
+{
+ ALIGNMENT = sizeof(void*) /* this is more of an educated guess; might want to adjust for your specific architecture */
+};
+static U8 * stackBuffer;
+static U8 * stackTop;
+static size_t stackSize;
+static size_t stackMaxSize;
+static bool isMemoryInitialised = false;
+IFDEBUG_MEMORY( static size_t maxUsedMemory = 0; );
+
+/*
+ * Initialise memory stack
+ */
+bool sysmem_init(void)
+{
+ if (isMemoryInitialised)
+ {
+ return true;
+ }
+
+ if (rb->audio_status())
+ {
+ /* Playback must be stopped the entire time the sound buffer is used.*/
+ rb->audio_stop();
+ }
+
+ stackBuffer = rb->plugin_get_audio_buffer(&stackMaxSize);
+ stackTop = stackBuffer;
+ stackSize = 0;
+ isMemoryInitialised = true;
+ return true;
+}
+
+/*
+ * Cleanup memory stack
+ */
+void sysmem_shutdown(void)
+{
+ if (!isMemoryInitialised)
+ {
+ return;
+ }
+
+ if (stackTop != stackBuffer || stackSize != 0)
+ {
+ sys_error("(memory) improper deallocation detected");
+ }
+
+ IFDEBUG_MEMORY(
+ sys_printf("xrick/memory: max memory usage was %u bytes\n", maxUsedMemory);
+ );
+
+ isMemoryInitialised = false;
+}
+
+/*
+ * Allocate a memory-aligned block on top of the memory stack
+ */
+void *sysmem_push(size_t size)
+{
+ uintptr_t alignedPtr;
+ size_t * allocatedSizePtr;
+
+ size_t neededSize = sizeof(size_t) + size + (ALIGNMENT - 1);
+ if (stackSize + neededSize > stackMaxSize)
+ {
+ sys_error("(memory) tried to allocate a block when memory full");
+ return NULL;
+ }
+
+ alignedPtr = (((uintptr_t)stackTop) + sizeof(size_t) + ALIGNMENT) & ~((uintptr_t)(ALIGNMENT - 1));
+
+ allocatedSizePtr = (size_t *)(alignedPtr);
+ allocatedSizePtr[-1] = neededSize;
+
+ stackTop += neededSize;
+ stackSize += neededSize;
+
+ IFDEBUG_MEMORY(
+ sys_printf("xrick/memory: allocated %u bytes\n", neededSize);
+ if (stackSize > maxUsedMemory) maxUsedMemory = stackSize;
+ );
+
+ return (void *)alignedPtr;
+}
+
+/*
+ * Release block from the top of the memory stack
+ */
+void sysmem_pop(void * alignedPtr)
+{
+ size_t allocatedSize;
+
+ if (!alignedPtr)
+ {
+ return;
+ }
+
+ if (stackSize == 0)
+ {
+ sys_error("(memory) tried to release a block when memory empty");
+ return;
+ }
+
+ allocatedSize = ((size_t *)(alignedPtr))[-1];
+ stackTop -= allocatedSize;
+ stackSize -= allocatedSize;
+
+ IFDEBUG_MEMORY(
+ if ((uintptr_t)alignedPtr != ((((uintptr_t)stackTop) + sizeof(size_t) + ALIGNMENT) & ~((uintptr_t)(ALIGNMENT - 1))))
+ {
+ sys_error("(memory) tried to release a wrong block");
+ return;
+ }
+ );
+
+ IFDEBUG_MEMORY(
+ sys_printf("xrick/memory: released %u bytes\n", allocatedSize);
+ );
+}
+
+/* eof */
diff --git a/apps/plugins/xrick/system/sysmenu_rockbox.c b/apps/plugins/xrick/system/sysmenu_rockbox.c
new file mode 100644
index 0000000..0049fd0
--- /dev/null
+++ b/apps/plugins/xrick/system/sysmenu_rockbox.c
@@ -0,0 +1,193 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "xrick/system/sysmenu_rockbox.h"
+
+#include "xrick/config.h"
+#include "xrick/control.h"
+#include "xrick/draw.h"
+#include "xrick/game.h"
+#include "xrick/system/system.h"
+#include "xrick/system/syssnd_rockbox.h"
+
+#include "plugin.h"
+#ifndef HAVE_LCD_COLOR
+#include "lib/grey.h"
+#endif
+
+#ifdef ENABLE_CHEATS
+/*
+ * Cheat settings menu
+ */
+static char * sysmenu_cheatItemText(int selected_item, void *data, char *buffer)
+{
+ (void)selected_item;
+ cheat_t cheat = (cheat_t)data;
+ (void)buffer;
+ char * messages[] =
+ {
+ "Disable Unlimited Lives/Ammo Mode",
+ "Enable Unlimited Lives/Ammo Mode",
+ "Disable Never Die Mode",
+ "Enable Never Die Mode",
+ "Disable Expose Mode",
+ "Enable Expose Mode"
+ };
+
+ switch (cheat)
+ {
+ case Cheat_UNLIMITED_ALL:
+ {
+ return game_cheat1? messages[0] : messages[1];
+ }
+ case Cheat_NEVER_DIE:
+ {
+ return game_cheat2? messages[2] : messages[3];
+ }
+ case Cheat_EXPOSE:
+ {
+ return game_cheat3? messages[4] : messages[5];
+ }
+ default: break;
+ }
+ return "";
+}
+
+/*
+ * Callback invoked by cheat menu item
+ */
+static int sysmenu_doToggleCheat(void *param)
+{
+ cheat_t cheat = (cheat_t)param;
+ game_toggleCheat(cheat);
+ return 0;
+}
+
+MENUITEM_FUNCTION_DYNTEXT(sysmenu_unlimitedAllItem, MENU_FUNC_USEPARAM,
+ sysmenu_doToggleCheat, (void *)Cheat_UNLIMITED_ALL,
+ sysmenu_cheatItemText, NULL, (void *)Cheat_UNLIMITED_ALL,
+ NULL, Icon_NOICON);
+
+MENUITEM_FUNCTION_DYNTEXT(sysmenu_neverDieItem, MENU_FUNC_USEPARAM,
+ sysmenu_doToggleCheat, (void *)Cheat_NEVER_DIE,
+ sysmenu_cheatItemText, NULL, (void *)Cheat_NEVER_DIE,
+ NULL, Icon_NOICON);
+
+MENUITEM_FUNCTION_DYNTEXT(sysmenu_exposeItem, MENU_FUNC_USEPARAM,
+ sysmenu_doToggleCheat, (void *)Cheat_EXPOSE,
+ sysmenu_cheatItemText, NULL, (void *)Cheat_EXPOSE,
+ NULL, Icon_NOICON);
+
+MAKE_MENU(sysmenu_cheatItems, "Cheat Settings", NULL, Icon_NOICON,
+ &sysmenu_unlimitedAllItem, &sysmenu_neverDieItem, &sysmenu_exposeItem);
+
+#endif /* ENABLE_CHEATS */
+
+/*
+ * Display main menu
+ */
+void sysmenu_exec(void)
+{
+ int result;
+ bool done;
+
+ enum
+ {
+ Menu_RESUME,
+ Menu_RESTART,
+#ifdef ENABLE_CHEATS
+ Menu_CHEAT_SETTINGS,
+#endif
+ Menu_QUIT
+ };
+
+ MENUITEM_STRINGLIST(sysmenu_mainItems, "xrick Menu", NULL,
+ "Resume Game",
+ "Restart Game",
+#ifdef ENABLE_CHEATS
+ "Cheat Settings",
+#endif
+ "Quit");
+
+#ifdef ENABLE_SOUND
+ syssnd_pauseAll(true);
+#endif
+
+#ifndef HAVE_LCD_COLOR
+ grey_show(false);
+#endif
+
+ done = false;
+ do
+ {
+ rb->button_clear_queue();
+
+ result = rb->do_menu(&sysmenu_mainItems, NULL, NULL, false);
+ switch(result)
+ {
+ case Menu_RESUME:
+ {
+ done = true;
+ break;
+ }
+ case Menu_RESTART:
+ {
+ control_set(Control_END);
+ done = true;
+ break;
+ }
+#ifdef ENABLE_CHEATS
+ case Menu_CHEAT_SETTINGS:
+ {
+ rb->do_menu(&sysmenu_cheatItems, NULL, NULL, false);
+ break;
+ }
+#endif
+ case Menu_QUIT:
+ {
+ control_set(Control_EXIT);
+ done = true;
+ break;
+ }
+ default: break;
+ }
+ } while (!done);
+
+#ifdef HAVE_LCD_COLOR
+ if (!(control_test(Control_EXIT)))
+ {
+ rb->memset(rb->lcd_framebuffer, 0, sizeof(fb_data) * LCD_WIDTH * LCD_HEIGHT);
+ sysvid_update(&draw_SCREENRECT);
+ rb->lcd_update();
+ }
+#else
+ grey_show(true);
+#endif
+
+#ifdef ENABLE_SOUND
+ syssnd_pauseAll(false);
+#endif
+}
+
+/* eof */
diff --git a/apps/plugins/xrick/system/sysmenu_rockbox.h b/apps/plugins/xrick/system/sysmenu_rockbox.h
new file mode 100644
index 0000000..fcd1360
--- /dev/null
+++ b/apps/plugins/xrick/system/sysmenu_rockbox.h
@@ -0,0 +1,32 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _SYSMENU_ROCKBOX_H
+#define _SYSMENU_ROCKBOX_H
+
+extern void sysmenu_exec(void);
+
+#endif /* ndef _SYSMENU_ROCKBOX_H */
+
+/* eof */
diff --git a/apps/plugins/xrick/system/syssnd_rockbox.c b/apps/plugins/xrick/system/syssnd_rockbox.c
new file mode 100644
index 0000000..2c3824a
--- /dev/null
+++ b/apps/plugins/xrick/system/syssnd_rockbox.c
@@ -0,0 +1,483 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "xrick/config.h"
+
+#ifdef ENABLE_SOUND
+
+#include "xrick/system/system.h"
+
+#include "xrick/game.h"
+#include "xrick/debug.h"
+#include "xrick/system/syssnd_rockbox.h"
+
+#include "plugin.h"
+
+/*
+ * Global variables
+ */
+const U8 syssnd_period = 20;
+
+/*
+ * Local variables
+ */
+enum
+{
+ SYSSND_MIX_CHANNELS = 5,
+ SYSSND_MIX_SAMPLES = 1024, /* try changing this value if sound mixing is too slow or choppy */
+ SYSSND_SOURCE_SAMPLES = SYSSND_MIX_SAMPLES / 2
+};
+
+/* channels to be mixed */
+static channel_t channels[SYSSND_MIX_CHANNELS];
+/* buffer used to mix sounds sent to pcm playback, stores 16b stereo 44Khz audio samples */
+enum { AUDIO_BUFFER_COUNT = 4 };
+typedef struct
+{
+ U32 data[SYSSND_MIX_SAMPLES];
+ size_t length; /* in 8 bit mono samples */
+} mix_buffer_t;
+static mix_buffer_t mixBuffers[AUDIO_BUFFER_COUNT];
+static size_t writeIndex;
+static size_t readIndex;
+static size_t fillCount;
+static bool isAudioPlaying;
+static bool isAudioInitialised = false;
+
+/*
+ * Prototypes
+ */
+static void endChannel(size_t c);
+static void get_more(const void **start, size_t *size);
+
+/*
+ * Deactivate channel
+ */
+static void endChannel(size_t c)
+{
+ channels[c].loop = 0;
+ channels[c].sound = NULL;
+}
+
+/*
+ * Audio callback
+ */
+static void get_more(const void **start, size_t *size)
+{
+ if (fillCount > 0)
+ {
+ /* Store output data address and size. */
+ *start = mixBuffers[readIndex].data;
+ *size = mixBuffers[readIndex].length * 8;
+
+ /* Free this part of output buffer. */
+ mixBuffers[readIndex].length = 0;
+
+ /* Advance to the next part of output buffer. */
+ readIndex = (readIndex + 1) & (AUDIO_BUFFER_COUNT - 1);
+ fillCount--;
+ }
+ else
+ {
+ /* Nothing to play. */
+ isAudioPlaying = false;
+ }
+}
+
+/*
+ * Mix audio samples and fill playback buffer
+ */
+void syssnd_update(void)
+{
+ if (!isAudioInitialised)
+ {
+ return;
+ }
+
+ for (;;)
+ {
+ size_t c;
+ size_t sampleOffset;
+ size_t maxSampleCount;
+ bool isFirstSound;
+ U8 *sourceBuf, *sourceBufEnd;
+ U32 *destBuf;
+
+ /* Cancel if whole buffer filled. */
+ if (fillCount >= (AUDIO_BUFFER_COUNT - 1))
+ {
+ return;
+ }
+
+ maxSampleCount = 0;
+
+ sampleOffset = mixBuffers[writeIndex].length;
+ destBuf = mixBuffers[writeIndex].data + sampleOffset * 2;
+
+ isFirstSound = true;
+ for (c = 0; c < SYSSND_MIX_CHANNELS ; ++c)
+ {
+ U32 * mixBuffer;
+ size_t sampleCount;
+ channel_t * channel = &channels[c];
+
+ if (!channel->sound /* no sound to play on this channel */
+ || (channel->loop == 0)) /* channel is inactive */
+ {
+ continue;
+ }
+
+ if (isFirstSound)
+ {
+ /* clear mixing buffer */
+ rb->memset(destBuf, 0, (SYSSND_MIX_SAMPLES - (sampleOffset * 2)) * sizeof(U32));
+ isFirstSound = false;
+ }
+
+ sampleCount = MIN(SYSSND_SOURCE_SAMPLES - sampleOffset, channel->len);
+ if (maxSampleCount < sampleCount)
+ {
+ maxSampleCount = sampleCount;
+ }
+
+ /* mix sound samples */
+ mixBuffer = destBuf;
+ sourceBuf = channel->buf;
+ sourceBufEnd = channel->buf + sampleCount;
+ while (sourceBuf < sourceBufEnd)
+ {
+ /* Convert from unsigned 8 bit mono 22khz to signed 16 bit stereo 44khz */
+ const int sourceSample = *sourceBuf++;
+ int monoSample = (sourceSample - 0x80) << 8;
+ U32 stereoSample = *mixBuffer;
+ monoSample += (S32)(stereoSample) >> 16;
+ if (monoSample >= 0x8000)
+ {
+ monoSample = 0x7FFF;
+ }
+ else if (monoSample < -0x8000)
+ {
+ monoSample = -0x8000;
+ }
+ stereoSample = (U16)monoSample | ((U16)monoSample << 16);
+ *mixBuffer++ = stereoSample;
+ *mixBuffer++ = stereoSample;
+ }
+ channel->buf = sourceBufEnd;
+
+ channel->len -= sampleCount;
+ if (channel->len == 0) /* ending ? */
+ {
+ if (channel->loop > 0)
+ {
+ channel->loop--;
+ }
+ if (channel->loop)
+ {
+ /* just loop */
+ IFDEBUG_AUDIO2(sys_printf("xrick/audio: channel %d - loop\n", c););
+ channel->buf = channel->sound->buf;
+ channel->len = channel->sound->len;
+ }
+ else
+ {
+ /* end for real */
+ IFDEBUG_AUDIO2(sys_printf("xrick/audio: channel %d - end\n", c););
+ endChannel(c);
+ }
+ }
+ }
+
+ if (maxSampleCount == 0)
+ {
+ return;
+ }
+
+ mixBuffers[writeIndex].length += maxSampleCount;
+
+ /* Advance one part of audio buffer. */
+ writeIndex = (writeIndex + 1) & (AUDIO_BUFFER_COUNT - 1);
+ fillCount++;
+
+ if (!isAudioPlaying && fillCount > 0)
+ {
+ rb->pcm_play_data(&get_more, NULL, NULL, 0);
+ isAudioPlaying = true;
+ }
+ }
+}
+
+/*
+ * Initialise audio
+ */
+bool syssnd_init(void)
+{
+ if (isAudioInitialised)
+ {
+ return true;
+ }
+
+ IFDEBUG_AUDIO(sys_printf("xrick/audio: start\n"););
+
+ rb->talk_disable(true);
+
+ /* Stop playback to reconfigure audio settings and acquire audio buffer */
+ rb->pcm_play_stop();
+
+#if INPUT_SRC_CAPS != 0
+ /* Select playback */
+ rb->audio_set_input_source(AUDIO_SRC_PLAYBACK, SRCF_PLAYBACK);
+ rb->audio_set_output_source(AUDIO_SRC_PLAYBACK);
+#endif
+
+ rb->pcm_set_frequency(HW_FREQ_44);
+ rb->pcm_apply_settings();
+
+ rb->memset(channels, 0, sizeof(channels));
+ rb->memset(mixBuffers, 0, sizeof(mixBuffers));
+
+ writeIndex = 0;
+ readIndex = 0;
+ fillCount = 0;
+ isAudioPlaying = false;
+
+ isAudioInitialised = true;
+ IFDEBUG_AUDIO(sys_printf("xrick/audio: ready\n"););
+ return true;
+}
+
+/*
+ * Shutdown
+ */
+void syssnd_shutdown(void)
+{
+ if (!isAudioInitialised)
+ {
+ return;
+ }
+
+ /* Stop playback. */
+ rb->pcm_play_stop();
+
+ /* Reset playing status. */
+ isAudioPlaying = false;
+
+ /* Restore default sampling rate. */
+ rb->pcm_set_frequency(HW_SAMPR_DEFAULT);
+ rb->pcm_apply_settings();
+
+ rb->talk_disable(false);
+
+ isAudioInitialised = false;
+ IFDEBUG_AUDIO(sys_printf("xrick/audio: stop\n"););
+}
+
+/*
+ * Play a sound
+ *
+ * loop: number of times the sound should be played, -1 to loop forever
+ *
+ * NOTE if sound is already playing, simply reset it (i.e. can not have
+ * twice the same sound playing -- tends to become noisy when too many
+ * bad guys die at the same time).
+ */
+void syssnd_play(sound_t *sound, S8 loop)
+{
+ size_t c;
+
+ if (!isAudioInitialised || !sound)
+ {
+ return;
+ }
+
+ c = 0;
+ while (channels[c].sound != sound &&
+ channels[c].loop != 0 &&
+ c < SYSSND_MIX_CHANNELS)
+ {
+ c++;
+ }
+ if (c >= SYSSND_MIX_CHANNELS)
+ {
+ return;
+ }
+
+ if (!sound->buf)
+ {
+ syssnd_load(sound);
+ if (!sound->buf)
+ {
+ sys_error("(audio) can not load %s", sound->name);
+ return;
+ }
+ }
+
+ IFDEBUG_AUDIO(
+ if (channels[c].sound == sound)
+ {
+ sys_printf("xrick/audio: already playing %s on channel %d - resetting\n",
+ sound->name, c);
+ }
+ else
+ {
+ sys_printf("xrick/audio: playing %s on channel %d\n", sound->name, c);
+ }
+ );
+
+ channels[c].loop = loop;
+ channels[c].sound = sound;
+ channels[c].buf = sound->buf;
+ channels[c].len = sound->len;
+}
+
+/*
+ * Pause all sounds
+ */
+void syssnd_pauseAll(bool pause)
+{
+ if (!isAudioInitialised)
+ {
+ return;
+ }
+
+ rb->pcm_play_lock();
+ rb->pcm_play_pause(!pause);
+ rb->pcm_play_unlock();
+}
+
+/*
+ * Stop a sound
+ */
+void syssnd_stop(sound_t *sound)
+{
+ size_t c;
+
+ if (!isAudioInitialised || !sound)
+ {
+ return;
+ }
+
+ for (c = 0; c < SYSSND_MIX_CHANNELS; c++)
+ {
+ if (channels[c].sound == sound)
+ {
+ endChannel(c);
+ }
+ }
+}
+
+/*
+ * Stops all channels.
+ */
+void syssnd_stopAll(void)
+{
+ size_t c;
+
+ if (!isAudioInitialised)
+ {
+ return;
+ }
+
+ for (c = 0; c < SYSSND_MIX_CHANNELS; c++)
+ {
+ if (channels[c].sound)
+ {
+ endChannel(c);
+ }
+ }
+}
+
+/*
+ * Load a sound.
+ */
+void syssnd_load(sound_t *sound)
+{
+ int bytesRead;
+ file_t fp;
+ bool success;
+
+ if (!isAudioInitialised || !sound)
+ {
+ return;
+ }
+
+ success = false;
+ do
+ {
+ sound->buf = sysmem_push(sound->len);
+ if (!sound->buf)
+ {
+ sys_error("(audio) not enough memory for \"%s\", %d bytes needed", sound->name, sound->len);
+ break;
+ }
+
+ fp = sysfile_open(sound->name);
+ if (!fp)
+ {
+ sys_error("(audio) unable to open \"%s\"", sound->name);
+ break;
+ }
+
+ sysfile_seek(fp, sizeof(wave_header_t), SEEK_SET); /* skip WAVE header */
+
+ bytesRead = sysfile_read(fp, sound->buf, sound->len, 1);
+ sysfile_close(fp);
+ if (bytesRead != 1)
+ {
+ sys_error("(audio) unable to read from \"%s\"", sound->name);
+ break;
+ }
+
+ success = true;
+ } while (false);
+
+ if (!success)
+ {
+ sysmem_pop(sound->buf);
+ sound->buf = NULL;
+ sound->len = 0;
+ return;
+ }
+
+ IFDEBUG_AUDIO(sys_printf("xrick/audio: successfully loaded \"%s\"\n", sound->name););
+}
+
+/*
+ * Unload a sound.
+ */
+void syssnd_unload(sound_t *sound)
+{
+ if (!isAudioInitialised || !sound || !sound->buf)
+ {
+ return;
+ }
+
+ sysmem_pop(sound->buf);
+ sound->buf = NULL;
+ sound->len = 0;
+}
+
+#endif /* ENABLE_SOUND */
+
+/* eof */
diff --git a/apps/plugins/xrick/system/syssnd_rockbox.h b/apps/plugins/xrick/system/syssnd_rockbox.h
new file mode 100644
index 0000000..41bd7d8
--- /dev/null
+++ b/apps/plugins/xrick/system/syssnd_rockbox.h
@@ -0,0 +1,48 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#ifndef _SYSSND_ROCKBOX_H
+#define _SYSSND_ROCKBOX_H
+
+#include "xrick/config.h"
+
+#ifdef ENABLE_SOUND
+
+#include "xrick/system/system.h"
+
+typedef struct {
+ sound_t *sound;
+ U8 *buf;
+ U32 len;
+ S8 loop;
+} channel_t;
+
+extern void syssnd_load(sound_t *);
+extern void syssnd_unload(sound_t *);
+
+#endif /* ENABLE_SOUND */
+
+#endif /* ndef _SYSSND_ROCKBOX_H */
+
+/* eof */
diff --git a/apps/plugins/xrick/system/system.h b/apps/plugins/xrick/system/system.h
new file mode 100644
index 0000000..2201c95
--- /dev/null
+++ b/apps/plugins/xrick/system/system.h
@@ -0,0 +1,180 @@
+/*
+ * xrick/system/system.h
+ *
+ * Copyright (C) 1998-2002 BigOrno (bigorno@bigorno.net).
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza.
+ * All rights reserved.
+ *
+ * The use and distribution terms for this software are contained in the file
+ * named README, which can be found in the root of this distribution. By
+ * using this software in any fashion, you are agreeing to be bound by the
+ * terms of this license.
+ *
+ * You must not remove this notice, or any other, from this software.
+ */
+
+#ifndef _SYSTEM_H
+#define _SYSTEM_H
+
+/*
+ * Detect GCC
+ */
+#ifdef __GNUC__
+/*
+ * make POSIX functions available
+ */
+# ifndef _POSIX_SOURCE
+# define _POSIX_SOURCE
+# endif
+#endif
+
+/*
+ * Detect Microsoft Visual C
+ */
+#ifdef _MSC_VER
+/*
+ * FIXME disable "integral size mismatch in argument; conversion supplied" warning
+ * as long as the code has not been cleared -- there are so many of them...
+ */
+#pragma warning( disable : 4761 )
+#endif
+
+/*
+ * Detect Microsoft Windows
+ */
+#if !defined( __WIN32__ ) && ( defined( WIN32 ) || defined( _WIN32 ) )
+#define __WIN32__
+#endif
+
+#include "xrick/config.h"
+#include "xrick/rects.h"
+#include "xrick/data/img.h"
+#ifdef ENABLE_SOUND
+#include "xrick/data/sounds.h"
+#endif
+
+#include <stddef.h> /* size_t */
+#include <sys/types.h> /* off_t */
+
+/*
+ * main section
+ */
+extern bool sys_init(int, char **);
+extern void sys_shutdown(void);
+extern void sys_error(const char *, ...);
+extern void sys_printf(const char *, ...);
+extern void sys_snprintf(char *, size_t, const char *, ...);
+extern size_t sys_strlen(const char *);
+extern U32 sys_gettime(void);
+extern void sys_yield(void);
+extern bool sys_cacheData(void);
+extern void sys_uncacheData(void);
+
+/*
+ * memory section
+ */
+extern bool sysmem_init(void);
+extern void sysmem_shutdown(void);
+extern void *sysmem_push(size_t);
+extern void sysmem_pop(void *);
+
+/*
+ * video section
+ */
+#define SYSVID_ZOOM 2
+#define SYSVID_MAXZOOM 4
+#define SYSVID_WIDTH 320
+#define SYSVID_HEIGHT 200
+
+extern U8 *sysvid_fb; /* frame buffer */
+
+extern bool sysvid_init(void);
+extern void sysvid_shutdown(void);
+extern void sysvid_update(const rect_t *);
+extern void sysvid_clear(void);
+extern void sysvid_zoom(S8);
+extern void sysvid_toggleFullscreen(void);
+extern void sysvid_setGamePalette(void);
+extern void sysvid_setPalette(img_color_t *, U16);
+
+/*
+ * file management section
+ */
+typedef void *file_t;
+
+extern const char *sysfile_defaultPath;
+
+extern bool sysfile_setRootPath(const char *);
+extern void sysfile_clearRootPath(void);
+
+extern file_t sysfile_open(const char *);
+extern int sysfile_seek(file_t file, long offset, int origin);
+extern int sysfile_tell(file_t);
+extern off_t sysfile_size(file_t);
+extern int sysfile_read(file_t, void *, size_t, size_t);
+extern void sysfile_close(file_t);
+
+/*
+ * events section
+ */
+extern void sysevt_poll(void);
+extern void sysevt_wait(void);
+
+/*
+ * keyboard section
+ */
+extern U8 syskbd_up;
+extern U8 syskbd_down;
+extern U8 syskbd_left;
+extern U8 syskbd_right;
+extern U8 syskbd_pause;
+extern U8 syskbd_end;
+extern U8 syskbd_xtra;
+extern U8 syskbd_fire;
+
+/*
+ * sound section
+ */
+#ifdef ENABLE_SOUND
+extern const U8 syssnd_period; /* time between each sound update, in millisecond */
+
+extern bool syssnd_init(void);
+extern void syssnd_shutdown(void);
+extern void syssnd_update(void);
+extern void syssnd_vol(S8);
+extern void syssnd_toggleMute(void);
+extern void syssnd_play(sound_t *, S8);
+extern void syssnd_pauseAll(bool);
+extern void syssnd_stop(sound_t *);
+extern void syssnd_stopAll(void);
+#endif /* ENABLE_ SOUND */
+
+/*
+ * args section
+ */
+extern int sysarg_args_period;
+extern int sysarg_args_map;
+extern int sysarg_args_submap;
+extern int sysarg_args_fullscreen;
+extern int sysarg_args_zoom;
+#ifdef ENABLE_SOUND
+extern bool sysarg_args_nosound;
+extern int sysarg_args_vol;
+#endif /* ENABLE_ SOUND */
+extern const char *sysarg_args_data;
+
+extern bool sysarg_init(int, char **);
+
+/*
+ * joystick section
+ */
+#ifdef ENABLE_JOYSTICK
+extern bool sysjoy_init(void);
+extern void sysjoy_shutdown(void);
+#endif
+
+#endif /* ndef _SYSTEM_H */
+
+/* eof */
+
+
diff --git a/apps/plugins/xrick/system/system_rockbox.c b/apps/plugins/xrick/system/system_rockbox.c
new file mode 100644
index 0000000..74de2ff
--- /dev/null
+++ b/apps/plugins/xrick/system/system_rockbox.c
@@ -0,0 +1,262 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "xrick/system/system.h"
+
+#include "xrick/config.h"
+#ifdef ENABLE_SOUND
+#include "xrick/system/syssnd_rockbox.h"
+#endif
+
+#include "plugin.h"
+
+enum { LINE_LENGTH = 80 };
+
+/*
+* Error
+*/
+void sys_error(const char *err, ...)
+{
+ va_list argptr;
+ char s[LINE_LENGTH];
+
+ /* prepare message */
+ va_start(argptr, err);
+ rb->vsnprintf(s, sizeof(s), err, argptr);
+ va_end(argptr);
+
+ /* print error message */
+ rb->splashf(HZ*3, "%s\nError!\n", s);
+ DEBUGF("%s\nError!\n", s);
+}
+
+/*
+* Print a message to standard output
+*/
+void sys_printf(const char *msg, ...)
+{
+ va_list argptr;
+ char s[LINE_LENGTH];
+
+ /* prepare message */
+ va_start(argptr, msg);
+ rb->vsnprintf(s, sizeof(s), msg, argptr);
+ va_end(argptr);
+
+ /* print message */
+ DEBUGF("%s",s);
+
+#ifdef ENABLE_SYSPRINTF_TO_SCREEN
+ {
+ static int currentYPos = 0;
+ size_t i;
+
+ /* Device LCDs display newlines funny. */
+ for(i = 0; s[i] != '\0'; ++i)
+ {
+ if(s[i] == '\n')
+ {
+ s[i] = ' ';
+ }
+ }
+
+ rb->lcd_putsxy(1, currentYPos, (unsigned char *)s);
+ rb->lcd_update();
+
+ currentYPos += 12;
+ if(currentYPos > LCD_HEIGHT-12)
+ {
+ currentYPos = 0;
+ rb->lcd_clear_display();
+ }
+ }
+#endif /* ENABLE_SYSPRINTF_TO_SCREEN */
+}
+
+/*
+* Print a message to string buffer
+*/
+void sys_snprintf(char *buf, size_t size, const char *msg, ...)
+{
+ va_list argptr;
+
+ va_start(argptr, msg);
+ rb->vsnprintf(buf, size, msg, argptr);
+ va_end(argptr);
+}
+
+/*
+* Returns string length
+*/
+size_t sys_strlen(const char * str)
+{
+ return rb->strlen(str);
+}
+
+/*
+* Return number of milliseconds elapsed since first call
+*/
+U32 sys_gettime(void)
+{
+ long ticks = *(rb->current_tick);
+ return (U32)((ticks * 1000) / HZ);
+}
+
+/*
+* Yield execution to another thread
+*/
+void sys_yield(void)
+{
+ rb->yield();
+}
+
+/*
+* Initialize system
+*/
+bool sys_init(int argc, char **argv)
+{
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(true);
+#endif
+
+ if (!sysarg_init(argc, argv))
+ {
+ return false;
+ }
+ if (!sysmem_init())
+ {
+ return false;
+ }
+ if (!sysvid_init())
+ {
+ return false;
+ }
+#ifdef ENABLE_SOUND
+ if (!sysarg_args_nosound && !syssnd_init())
+ {
+ return false;
+ }
+#endif
+ if (!sysfile_setRootPath(sysarg_args_data? sysarg_args_data : sysfile_defaultPath))
+ {
+ return false;
+ }
+ return true;
+}
+
+/*
+* Shutdown system
+*/
+void sys_shutdown(void)
+{
+ sysfile_clearRootPath();
+#ifdef ENABLE_SOUND
+ syssnd_shutdown();
+#endif
+ sysvid_shutdown();
+ sysmem_shutdown();
+
+#ifdef HAVE_ADJUSTABLE_CPU_FREQ
+ rb->cpu_boost(false);
+#endif
+}
+
+/*
+* Preload data before entering main loop
+*/
+bool sys_cacheData(void)
+{
+#ifdef ENABLE_SOUND
+ syssnd_load(soundGameover);
+ syssnd_load(soundSbonus2);
+ syssnd_load(soundBullet);
+ syssnd_load(soundBombshht);
+ syssnd_load(soundExplode);
+ syssnd_load(soundStick);
+ syssnd_load(soundWalk);
+ syssnd_load(soundCrawl);
+ syssnd_load(soundJump);
+ syssnd_load(soundPad);
+ syssnd_load(soundBox);
+ syssnd_load(soundBonus);
+ syssnd_load(soundSbonus1);
+ syssnd_load(soundDie);
+ syssnd_load(soundEntity[0]);
+ syssnd_load(soundEntity[1]);
+ syssnd_load(soundEntity[2]);
+ syssnd_load(soundEntity[3]);
+ syssnd_load(soundEntity[4]);
+ syssnd_load(soundEntity[5]);
+ syssnd_load(soundEntity[6]);
+ syssnd_load(soundEntity[7]);
+ syssnd_load(soundEntity[8]);
+ syssnd_load(soundTune0);
+ syssnd_load(soundTune1);
+ syssnd_load(soundTune2);
+ syssnd_load(soundTune3);
+ syssnd_load(soundTune4);
+ syssnd_load(soundTune5);
+#endif /* ENABLE_SOUND */
+ return true;
+}
+
+/*
+* Clear preloaded data before shutdown
+*/
+void sys_uncacheData(void)
+{
+#ifdef ENABLE_SOUND
+ syssnd_unload(soundTune5);
+ syssnd_unload(soundTune4);
+ syssnd_unload(soundTune3);
+ syssnd_unload(soundTune2);
+ syssnd_unload(soundTune1);
+ syssnd_unload(soundTune0);
+ syssnd_unload(soundEntity[8]);
+ syssnd_unload(soundEntity[7]);
+ syssnd_unload(soundEntity[6]);
+ syssnd_unload(soundEntity[5]);
+ syssnd_unload(soundEntity[4]);
+ syssnd_unload(soundEntity[3]);
+ syssnd_unload(soundEntity[2]);
+ syssnd_unload(soundEntity[1]);
+ syssnd_unload(soundEntity[0]);
+ syssnd_unload(soundDie);
+ syssnd_unload(soundSbonus1);
+ syssnd_unload(soundBonus);
+ syssnd_unload(soundBox);
+ syssnd_unload(soundPad);
+ syssnd_unload(soundJump);
+ syssnd_unload(soundCrawl);
+ syssnd_unload(soundWalk);
+ syssnd_unload(soundStick);
+ syssnd_unload(soundExplode);
+ syssnd_unload(soundBombshht);
+ syssnd_unload(soundBullet);
+ syssnd_unload(soundSbonus2);
+ syssnd_unload(soundGameover);
+#endif /* ENABLE_SOUND */
+}
+
+/* eof */
diff --git a/apps/plugins/xrick/system/sysvid_rockbox.c b/apps/plugins/xrick/system/sysvid_rockbox.c
new file mode 100644
index 0000000..c7586aa
--- /dev/null
+++ b/apps/plugins/xrick/system/sysvid_rockbox.c
@@ -0,0 +1,395 @@
+ /***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Port of xrick, a Rick Dangerous clone, to Rockbox.
+ * See http://www.bigorno.net/xrick/
+ *
+ * Copyright (C) 2008-2014 Pierluigi Vicinanza
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include "xrick/system/system.h"
+
+#include "xrick/config.h"
+#include "xrick/draw.h"
+#include "xrick/game.h"
+#include "xrick/data/img.h"
+#include "xrick/debug.h"
+
+#include "plugin.h"
+#include "lib/helper.h"
+
+/*
+ * Global variables
+ */
+U8 *sysvid_fb = NULL; /* xRick generic 320x200 8bpp frame buffer */
+
+/*
+ * Local variables
+ */
+static fb_data palette[256] IBSS_ATTR;
+static bool isVideoInitialised = false;
+#ifndef HAVE_LCD_COLOR
+# include "lib/grey.h"
+GREY_INFO_STRUCT_IRAM
+static unsigned char greybuffer[LCD_HEIGHT * LCD_WIDTH] IBSS_ATTR; /* off screen buffer */
+static unsigned char *gbuf;
+# if LCD_PIXELFORMAT == HORIZONTAL_PACKING
+enum { GREYBUFSIZE = (((LCD_WIDTH+7)/8)*LCD_HEIGHT*16+200) };
+# else
+enum { GREYBUFSIZE = (LCD_WIDTH*((LCD_HEIGHT+7)/8)*16+200) };
+# endif
+#endif /* ndef HAVE_LCD_COLOR */
+
+#if (LCD_HEIGHT < SYSVID_HEIGHT)
+enum { ROW_RESIZE_STEP = (LCD_HEIGHT << 16) / SYSVID_HEIGHT };
+
+static bool rowsToSkip[SYSVID_HEIGHT];
+
+/*
+ *
+ */
+static void calculateRowsToSkip(void)
+{
+ U32 currentRow, prevResizedRow;
+
+ prevResizedRow = 0;
+ rowsToSkip[0] = false;
+
+ for (currentRow = 1; currentRow < SYSVID_HEIGHT; ++currentRow)
+ {
+ U32 resizedRow = (currentRow * ROW_RESIZE_STEP) >> 16;
+ if (resizedRow == prevResizedRow)
+ {
+ rowsToSkip[currentRow] = true;
+ }
+ prevResizedRow = resizedRow;
+ }
+}
+#endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */
+
+#if (LCD_WIDTH < SYSVID_WIDTH)
+enum { COLUMN_RESIZE_STEP = (LCD_WIDTH << 16) / (SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)) };
+
+static bool columnsToSkip[SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)];
+
+/*
+ *
+ */
+static void calculateColumnsToSkip(void)
+{
+ U32 currentColumn, prevResizedColumn;
+
+ prevResizedColumn = 0;
+ columnsToSkip[0] = false;
+
+ for (currentColumn = 1; currentColumn < (SYSVID_WIDTH + (DRAW_XYMAP_SCRLEFT*2)); ++currentColumn)
+ {
+ U32 resizedColumn = (currentColumn * COLUMN_RESIZE_STEP) >> 16;
+ if (resizedColumn == prevResizedColumn)
+ {
+ columnsToSkip[currentColumn] = true;
+ }
+ prevResizedColumn = resizedColumn;
+ }
+}
+#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
+
+/*
+ *
+ */
+void sysvid_setPalette(img_color_t *pal, U16 n)
+{
+ U16 i;
+
+ for (i = 0; i < n; i++)
+ {
+#ifdef HAVE_LCD_COLOR
+ palette[i] = LCD_RGBPACK(pal[i].r, pal[i].g, pal[i].b);
+#else
+ palette[i] = ((3 * pal[i].r) + (6 * pal[i].g) + pal[i].b) / 10;
+#endif
+ }
+}
+
+/*
+ *
+ */
+void sysvid_setGamePalette()
+{
+ sysvid_setPalette(game_colors, game_color_count);
+}
+
+/*
+ * Update screen
+ */
+void sysvid_update(const rect_t *rects)
+{
+ unsigned sourceRow, sourceLastRow;
+ unsigned sourceColumn, sourceLastColumn;
+ unsigned resizedRow, resizedColumn;
+ unsigned resizedWidth, resizedHeight;
+ unsigned x, y;
+ U8 *sourceBuf, *sourceTemp;
+ fb_data *destBuf, *destTemp;
+
+ if (!rects)
+ {
+ return;
+ }
+
+ while (rects)
+ {
+ sourceRow = rects->y;
+ sourceLastRow = sourceRow + rects->height;
+ sourceColumn = rects->x;
+ sourceLastColumn = sourceColumn + rects->width;
+
+#if (LCD_WIDTH < SYSVID_WIDTH)
+ /* skip black borders */
+ if (sourceColumn < -DRAW_XYMAP_SCRLEFT)
+ {
+ sourceColumn = -DRAW_XYMAP_SCRLEFT;
+ }
+ if (sourceLastColumn > (SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT))
+ {
+ sourceLastColumn = SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT;
+ }
+
+ /* skip unwanted columns */
+ while (columnsToSkip[sourceColumn + DRAW_XYMAP_SCRLEFT] /* && sourceColumn < (SYSVID_WIDTH + DRAW_XYMAP_SCRLEFT) */)
+ {
+ ++sourceColumn;
+ }
+
+ resizedColumn = ((sourceColumn + DRAW_XYMAP_SCRLEFT) * COLUMN_RESIZE_STEP) >> 16;
+ resizedWidth = 0;
+#else
+ resizedColumn = sourceColumn;
+ resizedWidth = rects->width;
+#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
+
+#if (LCD_HEIGHT < SYSVID_HEIGHT)
+ /* skip unwanted rows */
+ while (rowsToSkip[sourceRow] /* && sourceRow < SYSVID_HEIGHT */)
+ {
+ ++sourceRow;
+ }
+
+ resizedRow = (sourceRow * ROW_RESIZE_STEP) >> 16;
+ resizedHeight = 0;
+#else
+ resizedRow = sourceRow;
+ resizedHeight = rects->height;
+#endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */
+
+ sourceBuf = sysvid_fb;
+ sourceBuf += sourceColumn + sourceRow * SYSVID_WIDTH;
+
+#ifdef HAVE_LCD_COLOR
+ destBuf = rb->lcd_framebuffer;
+#else
+ destBuf = greybuffer;
+#endif /* HAVE_LCD_COLOR */
+ destBuf += resizedColumn + resizedRow * LCD_WIDTH;
+
+#if (LCD_WIDTH < SYSVID_WIDTH)
+ sourceColumn += DRAW_XYMAP_SCRLEFT;
+ sourceLastColumn += DRAW_XYMAP_SCRLEFT;
+#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
+
+ for (y = sourceRow; y < sourceLastRow; ++y)
+ {
+#if (LCD_HEIGHT < SYSVID_HEIGHT)
+ if (rowsToSkip[y])
+ {
+ sourceBuf += SYSVID_WIDTH;
+ continue;
+ }
+
+ ++resizedHeight;
+#endif /* (LCD_HEIGHT < SYSVID_HEIGHT) */
+
+ sourceTemp = sourceBuf;
+ destTemp = destBuf;
+ for (x = sourceColumn; x < sourceLastColumn; ++x)
+ {
+#if (LCD_WIDTH < SYSVID_WIDTH)
+ if (columnsToSkip[x])
+ {
+ ++sourceTemp;
+ continue;
+ }
+
+ if (y == sourceRow)
+ {
+ ++resizedWidth;
+ }
+#endif /* (LCD_WIDTH < SYSVID_WIDTH) */
+
+ *destTemp = palette[*sourceTemp];
+
+ ++sourceTemp;
+ ++destTemp;
+ }
+
+ sourceBuf += SYSVID_WIDTH;
+ destBuf += LCD_WIDTH;
+ }
+
+#ifdef HAVE_LCD_COLOR
+ IFDEBUG_VIDEO2(
+ for (y = resizedRow; y < resizedRow + resizedHeight; ++y)
+ {
+ destBuf = rb->lcd_framebuffer + resizedColumn + y * LCD_WIDTH;
+ *destBuf = palette[0x01];
+ *(destBuf + resizedWidth - 1) = palette[0x01];
+ }
+
+ for (x = resizedColumn; x < resizedColumn + resizedWidth; ++x)
+ {
+ destBuf = rb->lcd_framebuffer + x + resizedRow * LCD_WIDTH;
+ *destBuf = palette[0x01];
+ *(destBuf + (resizedHeight - 1) * LCD_WIDTH) = palette[0x01];
+ }
+ );
+
+ rb->lcd_update_rect(resizedColumn, resizedRow, resizedWidth, resizedHeight);
+#else
+ grey_ub_gray_bitmap_part(greybuffer, resizedColumn, resizedRow, LCD_WIDTH, resizedColumn, resizedRow, resizedWidth, resizedHeight);
+#endif /* HAVE_LCD_COLOR */
+
+ rects = rects->next;
+ }
+}
+
+/*
+ * Clear screen
+ * (077C)
+ */
+void sysvid_clear(void)
+{
+ rb->memset(sysvid_fb, 0, sizeof(U8) * SYSVID_WIDTH * SYSVID_HEIGHT);
+}
+
+/*
+ * Initialise video
+ */
+bool sysvid_init()
+{
+ bool success;
+
+ if (isVideoInitialised)
+ {
+ return true;
+ }
+
+ IFDEBUG_VIDEO(sys_printf("xrick/video: start\n"););
+
+ success = false;
+ do
+ {
+ /* allocate xRick generic frame buffer into memory */
+ sysvid_fb = sysmem_push(sizeof(U8) * SYSVID_WIDTH * SYSVID_HEIGHT);
+ if (!sysvid_fb)
+ {
+ sys_error("(video) unable to allocate frame buffer");
+ break;
+ }
+
+#ifndef HAVE_LCD_COLOR
+ gbuf = sysmem_push(GREYBUFSIZE);
+ if (!gbuf)
+ {
+ sys_error("(video) unable to allocate buffer for greyscale functions");
+ break;
+ }
+
+ if (!grey_init(gbuf, GREYBUFSIZE, GREY_ON_COP, LCD_WIDTH, LCD_HEIGHT, NULL))
+ {
+ sys_error("(video) not enough memory to initialise greyscale functions");
+ break;
+ }
+#endif /* ndef HAVE_LCD_COLOR */
+
+ success = true;
+ } while (false);
+
+ if (!success)
+ {
+#ifndef HAVE_LCD_COLOR
+ sysmem_pop(gbuf);
+#endif
+ sysmem_pop(sysvid_fb);
+ return false;
+ }
+
+#if (LCD_HEIGHT < SYSVID_HEIGHT)
+ calculateRowsToSkip();
+#endif
+#if (LCD_WIDTH < SYSVID_WIDTH)
+ calculateColumnsToSkip();
+#endif
+
+#if LCD_DEPTH > 1
+ rb->lcd_set_backdrop(NULL);
+#endif
+ /* Turn off backlight timeout */
+ backlight_ignore_timeout();
+
+ rb->lcd_set_foreground(LCD_WHITE);
+ rb->lcd_set_background(LCD_BLACK);
+ rb->lcd_clear_display();
+
+#ifdef HAVE_LCD_COLOR
+ rb->lcd_update();
+#else
+ /* switch on greyscale overlay */
+ grey_show(true);
+#endif /* HAVE_LCD_COLOR */
+
+ isVideoInitialised = true;
+ IFDEBUG_VIDEO(sys_printf("xrick/video: ready\n"););
+ return true;
+}
+
+/*
+ * Shutdown video
+ */
+void sysvid_shutdown(void)
+{
+ if (!isVideoInitialised)
+ {
+ return;
+ }
+
+#ifndef HAVE_LCD_COLOR
+ grey_show(false);
+ grey_release();
+
+ sysmem_pop(gbuf);
+#endif /* ndef HAVE_LCD_COLOR */
+ sysmem_pop(sysvid_fb);
+
+ /* Turn on backlight timeout (revert to settings) */
+ backlight_use_settings();
+
+ isVideoInitialised = false;
+ IFDEBUG_VIDEO(sys_printf("xrick/video: stop\n"););
+}
+
+/* eof */