/*************************************************************************** * __________ __ ___. * Open \______ \ ____ ____ | | _\_ |__ _______ ___ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ * $Id$ * * Copyright (C) 2006 Jonathan Gordon * * * All files in this archive are subject to the GNU General Public License. * See the file COPYING in the source tree root for full license agreement. * * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY * KIND, either express or implied. * ****************************************************************************/ #include "plugin.h" #include "action.h" #include "pluginlib_actions.h" #if defined(HAVE_REMOTE_LCD) const struct button_mapping remote_directions[] = { #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || \ (CONFIG_KEYPAD == IRIVER_H300_PAD) { PLA_UP, BUTTON_RC_BITRATE, BUTTON_NONE}, { PLA_DOWN, BUTTON_RC_SOURCE, BUTTON_NONE}, { PLA_LEFT, BUTTON_RC_VOL_DOWN, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RC_VOL_UP, BUTTON_NONE}, { PLA_UP_REPEAT, BUTTON_RC_BITRATE|BUTTON_REPEAT, BUTTON_NONE}, { PLA_DOWN_REPEAT, BUTTON_RC_SOURCE|BUTTON_REPEAT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE}, #elif (CONFIG_KEYPAD == IAUDIO_X5M5_PAD) || \ (CONFIG_KEYPAD == IRIVER_H10_PAD) || \ (CONFIG_KEYPAD == GIGABEAT_PAD) { PLA_UP, BUTTON_RC_FF, BUTTON_NONE}, { PLA_DOWN, BUTTON_RC_REW, BUTTON_NONE}, { PLA_LEFT, BUTTON_RC_VOL_DOWN, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RC_VOL_UP, BUTTON_NONE}, { PLA_UP_REPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE}, { PLA_DOWN_REPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE}, #elif (CONFIG_KEYPAD == PLAYER_PAD) || \ (CONFIG_KEYPAD == RECORDER_PAD) { PLA_UP, BUTTON_RC_VOL_UP, BUTTON_NONE}, { PLA_DOWN, BUTTON_RC_VOL_DOWN, BUTTON_NONE}, { PLA_LEFT, BUTTON_RC_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RC_RIGHT, BUTTON_NONE}, { PLA_UP_REPEAT, BUTTON_RC_VOL_UP|BUTTON_REPEAT, BUTTON_NONE}, { PLA_DOWN_REPEAT, BUTTON_RC_VOL_DOWN|BUTTON_REPEAT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_RC_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RC_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, #else #error pluginlib_actions: Unsupported remote keypad #endif {CONTEXT_CUSTOM,BUTTON_NONE,BUTTON_NONE} }; #endif /* HAVE_REMOTE_LCD */ const struct button_mapping generic_directions[] = { #if (CONFIG_KEYPAD == IRIVER_H100_PAD) \ || (CONFIG_KEYPAD == IRIVER_H300_PAD) \ || (CONFIG_KEYPAD == IAUDIO_X5M5_PAD) \ || (CONFIG_KEYPAD == GIGABEAT_PAD) \ || (CONFIG_KEYPAD == RECORDER_PAD) \ || (CONFIG_KEYPAD == ARCHOS_AV300_PAD) \ || (CONFIG_KEYPAD == IRIVER_IFP7XX_PAD) \ || (CONFIG_KEYPAD == SANSA_C200_PAD) { PLA_UP, BUTTON_UP, BUTTON_NONE}, { PLA_DOWN, BUTTON_DOWN, BUTTON_NONE}, { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_UP_REPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE}, { PLA_DOWN_REPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) \ || (CONFIG_KEYPAD == IPOD_3G_PAD) \ || (CONFIG_KEYPAD == IPOD_4G_PAD) { PLA_UP, BUTTON_SCROLL_FWD, BUTTON_NONE}, { PLA_DOWN, BUTTON_SCROLL_BACK, BUTTON_NONE}, { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_UP_REPEAT, BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE}, { PLA_DOWN_REPEAT, BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == ONDIO_PAD { PLA_UP, BUTTON_UP, BUTTON_NONE}, { PLA_DOWN, BUTTON_DOWN, BUTTON_NONE}, { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_UP_REPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE}, { PLA_DOWN_REPEAT, BUTTON_DOWN|BUTTON_REPEAT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == PLAYER_PAD {PLA_UP, BUTTON_STOP, BUTTON_NONE}, {PLA_DOWN, BUTTON_PLAY, BUTTON_NONE}, {PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, {PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, {PLA_UP_REPEAT, BUTTON_STOP|BUTTON_REPEAT, BUTTON_NONE}, {PLA_DOWN_REPEAT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE}, {PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, {PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, #elif (CONFIG_KEYPAD == SANSA_E200_PAD) \ || (CONFIG_KEYPAD == IRIVER_H10_PAD) { PLA_UP, BUTTON_SCROLL_UP, BUTTON_NONE}, { PLA_DOWN, BUTTON_SCROLL_DOWN, BUTTON_NONE}, { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_UP_REPEAT, BUTTON_SCROLL_UP|BUTTON_REPEAT, BUTTON_NONE}, { PLA_DOWN_REPEAT, BUTTON_SCROLL_DOWN|BUTTON_REPEAT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, #elif (CONFIG_KEYPAD == MROBE500_PAD) { PLA_UP, BUTTON_RC_PLAY, BUTTON_NONE}, { PLA_DOWN, BUTTON_RC_DOWN, BUTTON_NONE}, { PLA_LEFT, BUTTON_RC_REW, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RC_FF, BUTTON_NONE}, { PLA_UP_REPEAT, BUTTON_RC_PLAY|BUTTON_REPEAT, BUTTON_NONE}, { PLA_DOWN_REPEAT, BUTTON_RC_DOWN|BUTTON_REPEAT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE}, #else #error pluginlib_actions: Unsupported keypad #endif {CONTEXT_CUSTOM,BUTTON_NONE,BUTTON_NONE} }; const struct button_mapping generic_left_right_fire[] = { #if (CONFIG_KEYPAD == IRIVER_H100_PAD) \ || (CONFIG_KEYPAD == IRIVER_H300_PAD) \ || (CONFIG_KEYPAD == IAUDIO_X5M5_PAD) \ || (CONFIG_KEYPAD == GIGABEAT_PAD) \ || (CONFIG_KEYPAD == IRIVER_IFP7XX_PAD) { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, { PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT,BUTTON_NONE}, #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) \ || (CONFIG_KEYPAD == IPOD_3G_PAD) \ || (CONFIG_KEYPAD == IPOD_4G_PAD) { PLA_LEFT, BUTTON_SCROLL_BACK, BUTTON_NONE}, { PLA_RIGHT, BUTTON_SCROLL_FWD, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_SCROLL_BACK|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_SCROLL_FWD|BUTTON_REPEAT, BUTTON_NONE}, { PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, { PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT,BUTTON_NONE}, #elif CONFIG_KEYPAD == ONDIO_PAD { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_FIRE, BUTTON_UP, BUTTON_NONE}, { PLA_FIRE_REPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == PLAYER_PAD { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_FIRE, BUTTON_ON, BUTTON_NONE}, { PLA_FIRE_REPEAT, BUTTON_ON|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == RECORDER_PAD { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_FIRE, BUTTON_PLAY, BUTTON_NONE}, { PLA_FIRE_REPEAT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE}, #elif (CONFIG_KEYPAD == SANSA_C200_PAD) \ || (CONFIG_KEYPAD == ARCHOS_AV300_PAD) { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, { PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT,BUTTON_NONE}, #elif (CONFIG_KEYPAD == SANSA_E200_PAD) { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, { PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT,BUTTON_NONE}, #elif (CONFIG_KEYPAD == IRIVER_H10_PAD) { PLA_LEFT, BUTTON_LEFT, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RIGHT, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_LEFT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RIGHT|BUTTON_REPEAT, BUTTON_NONE}, { PLA_FIRE, BUTTON_REW, BUTTON_NONE}, { PLA_FIRE_REPEAT, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE}, #elif (CONFIG_KEYPAD == MROBE500_PAD) { PLA_LEFT, BUTTON_RC_REW, BUTTON_NONE}, { PLA_RIGHT, BUTTON_RC_FF, BUTTON_NONE}, { PLA_LEFT_REPEAT, BUTTON_RC_REW|BUTTON_REPEAT, BUTTON_NONE}, { PLA_RIGHT_REPEAT, BUTTON_RC_FF|BUTTON_REPEAT, BUTTON_NONE}, { PLA_FIRE, BUTTON_RC_HEART, BUTTON_NONE}, { PLA_FIRE_REPEAT, BUTTON_RC_HEART|BUTTON_REPEAT, BUTTON_NONE}, #else #error pluginlib_actions: Unsupported keypad #endif {CONTEXT_CUSTOM,BUTTON_NONE,BUTTON_NONE} }; /* these were taken from the bubbles plugin, so may need tweaking */ const struct button_mapping generic_actions[] = { #if (CONFIG_KEYPAD == IRIVER_H100_PAD) || (CONFIG_KEYPAD == IRIVER_H300_PAD) {PLA_QUIT, BUTTON_OFF, BUTTON_NONE}, {PLA_QUIT, BUTTON_RC_STOP, BUTTON_NONE}, {PLA_START, BUTTON_ON, BUTTON_NONE}, {PLA_START, BUTTON_RC_ON, BUTTON_NONE}, {PLA_MENU, BUTTON_MODE, BUTTON_NONE}, {PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, {PLA_FIRE, BUTTON_RC_MENU, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_RC_MENU|BUTTON_REPEAT, BUTTON_NONE}, #elif (CONFIG_KEYPAD == IPOD_1G2G_PAD) \ || (CONFIG_KEYPAD == IPOD_3G_PAD) \ || (CONFIG_KEYPAD == IPOD_4G_PAD) {PLA_QUIT, BUTTON_MENU|BUTTON_SELECT, BUTTON_NONE}, {PLA_START, BUTTON_PLAY|BUTTON_REL, BUTTON_PLAY}, {PLA_MENU, BUTTON_MENU|BUTTON_REL, BUTTON_NONE}, {PLA_FIRE, BUTTON_SELECT|BUTTON_REL, BUTTON_SELECT}, {PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == IAUDIO_X5M5_PAD {PLA_QUIT, BUTTON_POWER, BUTTON_NONE}, {PLA_START, BUTTON_PLAY, BUTTON_NONE}, {PLA_START, BUTTON_RC_PLAY, BUTTON_NONE}, {PLA_MENU, BUTTON_REC, BUTTON_NONE}, {PLA_MENU, BUTTON_RC_MENU, BUTTON_NONE}, {PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, {PLA_FIRE, BUTTON_RC_MODE, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_RC_MODE|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == GIGABEAT_PAD {PLA_QUIT, BUTTON_A, BUTTON_NONE}, {PLA_START, BUTTON_POWER, BUTTON_NONE}, {PLA_MENU, BUTTON_MENU, BUTTON_NONE}, {PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == RECORDER_PAD {PLA_QUIT, BUTTON_OFF, BUTTON_NONE}, {PLA_START, BUTTON_ON, BUTTON_NONE}, {PLA_MENU, BUTTON_F1, BUTTON_NONE}, {PLA_FIRE, BUTTON_PLAY, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == ARCHOS_AV300_PAD {PLA_QUIT, BUTTON_OFF, BUTTON_NONE}, {PLA_START, BUTTON_ON, BUTTON_NONE}, {PLA_MENU, BUTTON_F1, BUTTON_NONE}, {PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == ONDIO_PAD {PLA_QUIT, BUTTON_OFF, BUTTON_NONE}, {PLA_START, BUTTON_MENU, BUTTON_NONE}, {PLA_MENU, BUTTON_DOWN, BUTTON_NONE}, {PLA_FIRE, BUTTON_UP, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_UP|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == PLAYER_PAD {PLA_QUIT, BUTTON_STOP|BUTTON_REPEAT, BUTTON_NONE}, {PLA_START, BUTTON_PLAY|BUTTON_REPEAT, BUTTON_NONE}, {PLA_MENU, BUTTON_MENU, BUTTON_NONE}, {PLA_FIRE, BUTTON_ON, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_ON|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == SANSA_E200_PAD {PLA_QUIT, BUTTON_POWER, BUTTON_NONE}, {PLA_START, BUTTON_UP, BUTTON_NONE}, {PLA_MENU, BUTTON_DOWN, BUTTON_NONE}, {PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == SANSA_C200_PAD {PLA_QUIT, BUTTON_POWER, BUTTON_NONE}, {PLA_START, BUTTON_UP, BUTTON_NONE}, {PLA_MENU, BUTTON_DOWN, BUTTON_NONE}, {PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == IRIVER_H10_PAD {PLA_QUIT, BUTTON_POWER, BUTTON_NONE}, {PLA_START, BUTTON_PLAY, BUTTON_NONE}, {PLA_MENU, BUTTON_FF, BUTTON_NONE}, {PLA_FIRE, BUTTON_REW, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_REW|BUTTON_REPEAT, BUTTON_NONE}, #elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD {PLA_QUIT, BUTTON_EQ, BUTTON_NONE}, {PLA_START, BUTTON_PLAY, BUTTON_NONE}, {PLA_MENU, BUTTON_MODE, BUTTON_NONE}, {PLA_FIRE, BUTTON_SELECT, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_SELECT|BUTTON_REPEAT, BUTTON_NONE}, #elif (CONFIG_KEYPAD == MROBE500_PAD) {PLA_QUIT, BUTTON_POWER, BUTTON_NONE}, {PLA_START, BUTTON_RC_PLAY, BUTTON_NONE}, {PLA_MENU, BUTTON_RC_MODE, BUTTON_NONE}, {PLA_FIRE, BUTTON_RC_HEART, BUTTON_NONE}, {PLA_FIRE_REPEAT, BUTTON_RC_HEART|BUTTON_REPEAT, BUTTON_NONE}, #else #error pluginlib_actions: Unsupported keypad #endif {CONTEXT_CUSTOM,BUTTON_NONE,BUTTON_NONE} }; static struct button_mapping **plugin_context_order; static int plugin_context_count = 0; static int last_context = 0; /* index into plugin_context_order of the last context returned */ const struct button_mapping* get_context_map(int context) { (void)context; if (last_contextget_custom_action(CONTEXT_CUSTOM,timeout,get_context_map); } ='n462' href='#n462'>462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 * $Id$
 *
 * Copyright (C) 2007-2008 Michael Sevakis (jhMikeS)
 * Copyright (C) 2006-2007 Adam Gashlin (hcs)
 * Copyright (C) 2004-2007 Shay Green (blargg)
 * Copyright (C) 2002 Brad Martin
 *
 * 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.
 *
 ****************************************************************************/

/* lovingly ripped off from Game_Music_Emu 0.5.2. http://www.slack.net/~ant/ */
/* DSP Based on Brad Martin's OpenSPC DSP emulator */
/* tag reading from sexyspc by John Brawn (John_Brawn@yahoo.com) and others */

#ifndef _SPC_CODEC_H_
#define _SPC_CODEC_H_

/* rather than comment out asserts, just define NDEBUG */
#ifndef NDEBUG
#define NDEBUG
#endif
#include <assert.h>

/** Basic configuration options **/

#ifndef ARM_ARCH
#define ARM_ARCH 0
#endif

#define SPC_DUAL_CORE 1

#if !defined(SPC_DUAL_CORE) || NUM_CORES == 1
#undef  SPC_DUAL_CORE
#define SPC_DUAL_CORE 0
#endif

/* Only some targets are fast enough for gaussian and realtime BRR decode */
#if CONFIG_CPU == S3C2440 || CONFIG_CPU == IMX31L || \
    CONFIG_CPU == AS3525 || CONFIG_CPU == AS3525v2 || \
    defined(CPU_S5L870X) || \
    (CONFIG_PLATFORM & PLATFORM_HOSTED) || MEMORYSIZE <= 2
    /* Don't cache BRR waves */
    #define SPC_BRRCACHE 0 
    
    /* Allow gaussian interpolation */
    #define SPC_NOINTERP 0

    /* Allow echo processing */
    #define SPC_NOECHO 0
#elif defined(CPU_COLDFIRE)
    /* Cache BRR waves */
    #define SPC_BRRCACHE 1 
    
    /* Disable gaussian interpolation */
    #define SPC_NOINTERP 1

    /* Allow echo processing */
    #define SPC_NOECHO 0
#elif defined (CPU_PP) && SPC_DUAL_CORE
    /* Cache BRR waves */
    #define SPC_BRRCACHE 1 
    
    /* Disable gaussian interpolation */
    #define SPC_NOINTERP 1

    /* Allow echo processing */
    #define SPC_NOECHO 0
#else
    /* Cache BRR waves */
    #define SPC_BRRCACHE 1 
    
    /* Disable gaussian interpolation */
    #define SPC_NOINTERP 1

    /* Disable echo processing */
    #define SPC_NOECHO 1
#endif

#if   (CONFIG_CPU == MCF5250)
#define IBSS_ATTR_SPC               IBSS_ATTR
#define ICODE_ATTR_SPC              ICODE_ATTR
#define ICONST_ATTR_SPC             ICONST_ATTR
/* Not enough IRAM available to move further data to it. */
#define IBSS_ATTR_SPC_LARGE_IRAM

#elif (CONFIG_CPU == PP5020)
/* spc is slower on PP5020 when moving data to IRAM. */
#define IBSS_ATTR_SPC
#define ICODE_ATTR_SPC
#define ICONST_ATTR_SPC
/* Not enough IRAM available to move further data to it. */
#define IBSS_ATTR_SPC_LARGE_IRAM

#elif (CONFIG_CPU == PP5022) || (CONFIG_CPU == PP5024)
#define IBSS_ATTR_SPC               IBSS_ATTR
#define ICODE_ATTR_SPC              ICODE_ATTR
#define ICONST_ATTR_SPC             ICONST_ATTR
/* Not enough IRAM available to move further data to it. */
#define IBSS_ATTR_SPC_LARGE_IRAM

#elif defined(CPU_S5L870X)
#define IBSS_ATTR_SPC               IBSS_ATTR
#define ICODE_ATTR_SPC              ICODE_ATTR
#define ICONST_ATTR_SPC             ICONST_ATTR
/* Very large IRAM. Move even more data to it. */
#define IBSS_ATTR_SPC_LARGE_IRAM    IBSS_ATTR

#else
#define IBSS_ATTR_SPC               IBSS_ATTR
#define ICODE_ATTR_SPC              ICODE_ATTR
#define ICONST_ATTR_SPC             ICONST_ATTR
/* Not enough IRAM available to move further data to it. */
#define IBSS_ATTR_SPC_LARGE_IRAM
#endif

#if SPC_DUAL_CORE
    #undef SHAREDBSS_ATTR
    #define SHAREDBSS_ATTR __attribute__ ((section(".ibss")))
    #undef SHAREDDATA_ATTR
    #define SHAREDDATA_ATTR __attribute__((section(".idata")))
#endif

/* Samples per channel per iteration */
#if defined(CPU_PP) && NUM_CORES == 1
#define WAV_CHUNK_SIZE 2048
#else
#define WAV_CHUNK_SIZE 1024
#endif

/**************** Little-endian handling ****************/

static inline unsigned get_le16( void const* p )
{
    return  ((unsigned char const*) p) [1] * 0x100u +
            ((unsigned char const*) p) [0];
}

static inline int get_le16s( void const* p )
{
    return  ((signed char const*) p) [1] * 0x100 +
            ((unsigned char const*) p) [0];
}

static inline void set_le16( void* p, unsigned n )
{
    ((unsigned char*) p) [1] = (unsigned char) (n >> 8);
    ((unsigned char*) p) [0] = (unsigned char) n;
}

#define GET_LE16( addr )        get_le16( addr )
#define GET_LE16A( addr )       get_le16( addr )
#define SET_LE16( addr, data )  set_le16( addr, data )
#define INT16A( addr ) (*(uint16_t*) (addr))
#define INT16SA( addr ) (*(int16_t*) (addr))

#ifdef ROCKBOX_LITTLE_ENDIAN
    #define GET_LE16SA( addr )      (*( int16_t*) (addr))
    #define SET_LE16A( addr, data ) (void) (*(uint16_t*) (addr) = (data))
#else
    #define GET_LE16SA( addr )      get_le16s( addr )
    #define SET_LE16A( addr, data ) set_le16 ( addr, data )
#endif

struct Spc_Emu;
#define THIS struct Spc_Emu* const this

/* The CPU portion (shock!) */

struct cpu_regs_t
{
    long pc; /* more than 16 bits to allow overflow detection */
    uint8_t a;
    uint8_t x;
    uint8_t y;
    uint8_t status;
    uint8_t sp;
};

struct src_dir
{
    uint16_t start;
    uint16_t loop;
};

struct cpu_ram_t
{
    union {
        uint8_t padding1 [0x100];
        uint16_t align;
    } padding1 [1];
    union {
        uint8_t ram       [0x10000];
        struct src_dir sd [0x10000/sizeof(struct src_dir)];
    };
    uint8_t padding2 [0x100];
};

#undef RAM
#define RAM ram.ram
extern struct cpu_ram_t ram;

long CPU_run( THIS, long start_time ) ICODE_ATTR_SPC;
void CPU_Init( THIS );

/* The DSP portion (awe!) */
enum { VOICE_COUNT = 8 };
enum { REGISTER_COUNT = 128 };

struct raw_voice_t
{
    int8_t  volume [2];
    uint8_t rate [2];
    uint8_t waveform;
    uint8_t adsr [2];   /* envelope rates for attack, decay, and sustain */
    uint8_t gain;       /* envelope gain (if not using ADSR) */
    int8_t  envx;       /* current envelope level */
    int8_t  outx;       /* current sample */
    int8_t  unused [6];
};
    
struct globals_t
{
    int8_t  unused1 [12];
    int8_t  volume_0;         /* 0C   Main Volume Left (-.7) */
    int8_t  echo_feedback;    /* 0D   Echo Feedback (-.7) */
    int8_t  unused2 [14];
    int8_t  volume_1;         /* 1C   Main Volume Right (-.7) */
    int8_t  unused3 [15];
    int8_t  echo_volume_0;    /* 2C   Echo Volume Left (-.7) */
    uint8_t pitch_mods;       /* 2D   Pitch Modulation on/off for each voice */
    int8_t  unused4 [14];
    int8_t  echo_volume_1;    /* 3C   Echo Volume Right (-.7) */
    uint8_t noise_enables;    /* 3D   Noise output on/off for each voice */
    int8_t  unused5 [14];
    uint8_t key_ons;          /* 4C   Key On for each voice */
    uint8_t echo_ons;         /* 4D   Echo on/off for each voice */
    int8_t  unused6 [14];
    uint8_t key_offs;         /* 5C   key off for each voice
                                      (instantiates release mode) */
    uint8_t wave_page;        /* 5D   source directory (wave table offsets) */
    int8_t  unused7 [14];
    uint8_t flags;            /* 6C   flags and noise freq */
    uint8_t echo_page;        /* 6D */
    int8_t  unused8 [14];
    uint8_t wave_ended;       /* 7C */
    uint8_t echo_delay;       /* 7D   ms >> 4 */
    char    unused9 [2];
};

enum state_t
{  /* -1, 0, +1 allows more efficient if statements */
    state_decay   = -1,
    state_sustain = 0,
    state_attack  = +1,
    state_release = 2
};

struct cache_entry_t
{
    int16_t const* samples;
    unsigned end; /* past-the-end position */
    unsigned loop; /* number of samples in loop */
    unsigned start_addr;
};

enum { BRR_BLOCK_SIZE = 16 };
enum { BRR_CACHE_SIZE = 0x20000 + 32} ;

struct voice_t
{
#if SPC_BRRCACHE
    int16_t const* samples;
    long wave_end;
    int wave_loop;
#else
    int16_t samples [3 + BRR_BLOCK_SIZE + 1];
    int block_header; /* header byte from current block */
#endif
    uint8_t const* addr;
    short volume [2];
    long position;/* position in samples buffer, with 12-bit fraction */
    short envx;
    short env_mode;
    short env_timer;
    short key_on_delay;
};

#if SPC_BRRCACHE
/* a little extra for samples that go past end */
extern int16_t BRRcache [BRR_CACHE_SIZE];
#endif

enum { FIR_BUF_HALF = 8 };

#if defined(CPU_COLDFIRE)
/* global because of the large aligment requirement for hardware masking -
 * L-R interleaved 16-bit samples for easy loading and mac.w use.
 */
enum
{
    FIR_BUF_CNT   = FIR_BUF_HALF,
    FIR_BUF_SIZE  = FIR_BUF_CNT * sizeof ( int32_t ),
    FIR_BUF_ALIGN = FIR_BUF_SIZE * 2,
    FIR_BUF_MASK  = ~((FIR_BUF_ALIGN / 2) | (sizeof ( int32_t ) - 1))
};
#elif defined (CPU_ARM)
#if ARM_ARCH >= 6
enum
{
    FIR_BUF_CNT   = FIR_BUF_HALF * 2,
    FIR_BUF_SIZE  = FIR_BUF_CNT * sizeof ( int32_t ),
    FIR_BUF_ALIGN = FIR_BUF_SIZE,
    FIR_BUF_MASK  = ~((FIR_BUF_ALIGN / 2) | (sizeof ( int32_t ) - 1))
};
#else
enum
{
    FIR_BUF_CNT   = FIR_BUF_HALF * 2 * 2,
    FIR_BUF_SIZE  = FIR_BUF_CNT * sizeof ( int32_t ),
    FIR_BUF_ALIGN = FIR_BUF_SIZE,
    FIR_BUF_MASK  = ~((FIR_BUF_ALIGN / 2) | (sizeof ( int32_t ) * 2 - 1))
};
#endif /* ARM_ARCH */
#endif /* CPU_* */

struct Spc_Dsp
{
    union
    {
        struct raw_voice_t voice [VOICE_COUNT];
        uint8_t reg [REGISTER_COUNT];
        struct globals_t g;
        int16_t align;
    } r;
    
    unsigned echo_pos;
    int keys_down;
    int noise_count;
    uint16_t noise; /* also read as int16_t */
    
#if defined(CPU_COLDFIRE)
    /* FIR history is interleaved. Hardware handles wrapping by mask.
     * |LR|LR|LR|LR|LR|LR|LR|LR| */
    int32_t *fir_ptr;
    /* wrapped address just behind current position -
       allows mac.w to increment and mask fir_ptr */
    int32_t *last_fir_ptr;
    /* copy of echo FIR constants as int16_t for use with mac.w */
    int16_t fir_coeff [VOICE_COUNT];
#elif defined (CPU_ARM)
   /* fir_buf [i + 8] == fir_buf [i], to avoid wrap checking in FIR code */
    int32_t *fir_ptr;
#if ARM_ARCH >= 6
    /* FIR history is interleaved with guard to eliminate wrap checking
     * when convolving.
     * |LR|LR|LR|LR|LR|LR|LR|LR|--|--|--|--|--|--|--|--| */
    /* copy of echo FIR constants as int16_t, loaded as int32 for
     * halfword, packed multiples */
    int16_t fir_coeff [VOICE_COUNT];
#else
    /* FIR history is interleaved with guard to eliminate wrap checking
     * when convolving.
     * |LL|RR|LL|RR|LL|RR|LL|RR|LL|RR|LL|RR|LL|RR|LL|RR|...
     * |--|--|--|--|--|--|--|--|--|--|--|--|--|--|--|--| */
    /* copy of echo FIR constants as int32_t, for faster access */
    int32_t fir_coeff [VOICE_COUNT]; 
#endif /* ARM_ARCH */
#else /* Unoptimized CPU */
    /* fir_buf [i + 8] == fir_buf [i], to avoid wrap checking in FIR code */
    int fir_pos; /* (0 to 7) */
    int fir_buf [FIR_BUF_HALF * 2] [2];
    /* copy of echo FIR constants as int, for faster access */
    int fir_coeff [VOICE_COUNT]; 
#endif
    
    struct voice_t voice_state [VOICE_COUNT];
    
#if SPC_BRRCACHE
    uint8_t oldsize;
    struct cache_entry_t wave_entry     [256];
    struct cache_entry_t wave_entry_old [256];
#endif
};

void DSP_run_( struct Spc_Dsp* this, long count, int32_t* out_buf ) ICODE_ATTR_SPC;
void DSP_reset( struct Spc_Dsp* this );

static inline void DSP_run( struct Spc_Dsp* this, long count, int32_t* out )
{
    /* Should we just fill the buffer with silence? Flags won't be cleared */
    /* during this run so it seems it should keep resetting every sample. */
    if ( this->r.g.flags & 0x80 )
        DSP_reset( this );