From 102c3742487dba76ec72d5f56a2c3041344b2d68 Mon Sep 17 00:00:00 2001 From: Sebastian Leonhardt Date: Fri, 8 Jan 2016 01:05:36 +0100 Subject: 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 Further changes: * Additonal fixes from g#3026 * Port to modern plugin API * Add Pluginlib keymap fallback * Support all >1bpp screens * Fix build warnings in miniz * Better error message when resources are missing Change-Id: Id83928bc2539901b0221692f65cbca41389c58e7 --- apps/plugins/xrick/system/basic_funcs.c | 33 ++ apps/plugins/xrick/system/basic_funcs.h | 141 ++++++++ apps/plugins/xrick/system/basic_types.h | 48 +++ apps/plugins/xrick/system/main_rockbox.c | 43 +++ apps/plugins/xrick/system/miniz_config.h | 38 +++ apps/plugins/xrick/system/rockboxcodes.h | 110 +++++++ apps/plugins/xrick/system/sysarg_rockbox.c | 49 +++ apps/plugins/xrick/system/sysevt_rockbox.c | 156 +++++++++ apps/plugins/xrick/system/sysfile_rockbox.c | 122 +++++++ apps/plugins/xrick/system/sysmem_rockbox.c | 156 +++++++++ apps/plugins/xrick/system/sysmenu_rockbox.c | 200 ++++++++++++ apps/plugins/xrick/system/sysmenu_rockbox.h | 32 ++ apps/plugins/xrick/system/syssnd_rockbox.c | 483 ++++++++++++++++++++++++++++ apps/plugins/xrick/system/syssnd_rockbox.h | 48 +++ apps/plugins/xrick/system/system.h | 178 ++++++++++ apps/plugins/xrick/system/system_rockbox.c | 262 +++++++++++++++ apps/plugins/xrick/system/sysvid_rockbox.c | 402 +++++++++++++++++++++++ 17 files changed, 2501 insertions(+) create mode 100644 apps/plugins/xrick/system/basic_funcs.c create mode 100644 apps/plugins/xrick/system/basic_funcs.h create mode 100644 apps/plugins/xrick/system/basic_types.h create mode 100644 apps/plugins/xrick/system/main_rockbox.c create mode 100644 apps/plugins/xrick/system/miniz_config.h create mode 100644 apps/plugins/xrick/system/rockboxcodes.h create mode 100644 apps/plugins/xrick/system/sysarg_rockbox.c create mode 100644 apps/plugins/xrick/system/sysevt_rockbox.c create mode 100644 apps/plugins/xrick/system/sysfile_rockbox.c create mode 100644 apps/plugins/xrick/system/sysmem_rockbox.c create mode 100644 apps/plugins/xrick/system/sysmenu_rockbox.c create mode 100644 apps/plugins/xrick/system/sysmenu_rockbox.h create mode 100644 apps/plugins/xrick/system/syssnd_rockbox.c create mode 100644 apps/plugins/xrick/system/syssnd_rockbox.h create mode 100644 apps/plugins/xrick/system/system.h create mode 100644 apps/plugins/xrick/system/system_rockbox.c create mode 100644 apps/plugins/xrick/system/sysvid_rockbox.c (limited to 'apps/plugins/xrick/system') diff --git a/apps/plugins/xrick/system/basic_funcs.c b/apps/plugins/xrick/system/basic_funcs.c new file mode 100644 index 0000000000..fbc025a6ef --- /dev/null +++ b/apps/plugins/xrick/system/basic_funcs.c @@ -0,0 +1,33 @@ +/* + * 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 0000000000..1ac5c58d32 --- /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 /* _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 +# 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 +# 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 +# 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 '? */ +# 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 0000000000..e05fd477f3 --- /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 +#include + +#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 0000000000..e273e1dc8d --- /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 0000000000..65899b0c23 --- /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 0000000000..ca56c338b6 --- /dev/null +++ b/apps/plugins/xrick/system/rockboxcodes.h @@ -0,0 +1,110 @@ + /*************************************************************************** + * __________ __ ___. + * 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_YH92X_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 +# include "lib/pluginlib_actions.h" +#define XRICK_BTN_UP PLA_UP +#define XRICK_BTN_DOWN PLA_DOWN +#define XRICK_BTN_LEFT PLA_LEFT +#define XRICK_BTN_RIGHT PLA_RIGHT +#define XRICK_BTN_FIRE PLA_SELECT +#define XRICK_BTN_PAUSE PLA_CANCEL +#define XRICK_BTN_MENU PLA_EXIT +#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 0000000000..fa502ff4b0 --- /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 100644 index 0000000000..f5314712e8 --- /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 0000000000..72227d5301 --- /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 ROCKBOX_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 0000000000..06a683a463 --- /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 0000000000..fb80881749 --- /dev/null +++ b/apps/plugins/xrick/system/sysmenu_rockbox.c @@ -0,0 +1,200 @@ + /*************************************************************************** + * __________ __ ___. + * 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 HAVE_LCD_COLOR +static fb_data *lcd_fb=NULL; +#endif + +#ifdef ENABLE_CHEATS +/* + * Cheat settings menu + */ +static char * sysmenu_cheatItemText(int selected_item, void *data, char *buffer, size_t buffer_len) +{ + (void)selected_item; + cheat_t cheat = (cheat_t)data; + (void)buffer; + (void)buffer_len; + 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, + sysmenu_cheatItemText, NULL, (void *)Cheat_UNLIMITED_ALL, + NULL, Icon_NOICON); + +MENUITEM_FUNCTION_DYNTEXT(sysmenu_neverDieItem, MENU_FUNC_USEPARAM, sysmenu_doToggleCheat, + sysmenu_cheatItemText, NULL, (void *)Cheat_NEVER_DIE, + NULL, Icon_NOICON); + +MENUITEM_FUNCTION_DYNTEXT(sysmenu_exposeItem, MENU_FUNC_USEPARAM, sysmenu_doToggleCheat, + 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 + ID2P(LANG_MENU_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))) + { + if(!lcd_fb) + { + struct viewport *vp_main = rb->lcd_set_viewport(NULL); + lcd_fb = vp_main->buffer->fb_ptr; + } + rb->memset(lcd_fb, 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 0000000000..fcd13606fa --- /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 0000000000..97ed5474f1 --- /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->mixer_channel_stop(PCM_MIXER_CHAN_PLAYBACK); + +#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->mixer_channel_play_pause(PCM_MIXER_CHAN_PLAYBACK, !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 0000000000..41bd7d8454 --- /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 0000000000..d4dda3d5d4 --- /dev/null +++ b/apps/plugins/xrick/system/system.h @@ -0,0 +1,178 @@ +/* + * 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 /* size_t */ +#include /* 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 0000000000..3b5f96a4ed --- /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, ID2P(LANG_ERROR_FORMATSTR), s); + DEBUGF("Error: %s\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 0000000000..236bc87616 --- /dev/null +++ b/apps/plugins/xrick/system/sysvid_rockbox.c @@ -0,0 +1,402 @@ + /*************************************************************************** + * __________ __ ___. + * 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 */ + +static fb_data *lcd_fb = NULL; + +#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 + if(!lcd_fb) + { + struct viewport *vp_main = rb->lcd_set_viewport(NULL); + lcd_fb = vp_main->buffer->fb_ptr; + } + destBuf = lcd_fb; +#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 = lcd_fb + resizedColumn + y * LCD_WIDTH; + *destBuf = palette[0x01]; + *(destBuf + resizedWidth - 1) = palette[0x01]; + } + + for (x = resizedColumn; x < resizedColumn + resizedWidth; ++x) + { + destBuf = rb->lcd_fb + 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 */ -- cgit v1.2.3