1
0
Fork 0
forked from len0rd/rockbox

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
This commit is contained in:
Sebastian Leonhardt 2016-01-08 01:05:36 +01:00 committed by Solomon Peachy
parent 6f1e67e5e3
commit 102c374248
88 changed files with 16514 additions and 62 deletions

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 */

View file

@ -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 <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 */

View file

@ -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 */

View file

@ -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 */