rockbox/apps/plugins/rockboy/rockboy.c
Tomasz Malesinski 80da8b141c FS#6357, patch 1: let iramcopy and bss share the same space in codecs and
plugins. Currently, in case of plugins using IRAM bss is cleared twice,
once in the loader, once in PLUGIN_IRAM_INIT. For codecs, bss is cleared only
during codec initialization. Also, removed double variables in codecs
storing a pointer to codec_api.


git-svn-id: svn://svn.rockbox.org/rockbox/trunk@11606 a1c6a512-1295-4272-9138-f99709370657
2006-11-26 18:31:41 +00:00

216 lines
5.4 KiB
C

/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Gameboy emulator based on gnuboy
*
* 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 "loader.h"
#include "rockmacros.h"
PLUGIN_HEADER
PLUGIN_IRAM_DECLARE
/* here is a global api struct pointer. while not strictly necessary,
it's nice not to have to pass the api pointer in all function calls
in the plugin */
struct plugin_api* rb;
int shut,cleanshut;
char *errormsg;
int gnuboy_main(char *rom);
void pcm_close(void);
#define optionname "options"
void die(char *message, ...)
{
shut=1;
errormsg=message;
}
struct options options;
void *audio_bufferbase;
void *audio_bufferpointer;
unsigned int audio_buffer_free;
void *my_malloc(size_t size)
{
void *alloc;
if (size + 4 > audio_buffer_free)
return 0;
alloc = audio_bufferpointer;
audio_bufferpointer += size + 4;
audio_buffer_free -= size + 4;
return alloc;
}
/* Using #define isn't enough with GCC 4.0.1 */
void* memcpy(void* dst, const void* src, size_t size)
{
return rb->memcpy(dst, src, size);
}
void setmallocpos(void *pointer)
{
audio_bufferpointer = pointer;
audio_buffer_free = audio_bufferpointer - audio_bufferbase;
}
void setoptions (void)
{
int fd;
DIR* dir;
char optionsave[sizeof(savedir)+sizeof(optionname)];
dir=opendir(savedir);
if(!dir)
mkdir(savedir,0);
else
closedir(dir);
snprintf(optionsave, sizeof(optionsave), "%s/%s", savedir, optionname);
fd = open(optionsave, O_RDONLY);
if(fd < 0) // no options to read, set defaults
{
#if (CONFIG_KEYPAD == IRIVER_H100_PAD)
options.A=BUTTON_ON;
options.B=BUTTON_OFF;
options.START=BUTTON_REC;
options.SELECT=BUTTON_SELECT;
options.MENU=BUTTON_MODE;
#elif (CONFIG_KEYPAD == IRIVER_H300_PAD)
options.A=BUTTON_REC;
options.B=BUTTON_MODE;
options.START=BUTTON_ON;
options.SELECT=BUTTON_SELECT;
options.MENU=BUTTON_OFF;
#elif CONFIG_KEYPAD == RECORDER_PAD
options.A=BUTTON_F1;
options.B=BUTTON_F2;
options.START=BUTTON_F3;
options.SELECT=BUTTON_PLAY;
options.MENU=BUTTON_OFF;
#elif CONFIG_KEYPAD == IPOD_4G_PAD
options.A=BUTTON_NONE;
options.B=BUTTON_NONE;
options.START=BUTTON_SELECT;
options.SELECT=BUTTON_NONE;
options.MENU=(BUTTON_SELECT | BUTTON_REPEAT);
#elif CONFIG_KEYPAD == IRIVER_IFP7XX_PAD
options.A=BUTTON_PLAY;
options.B=BUTTON_EQ;
options.START=BUTTON_MODE;
options.SELECT=(BUTTON_SELECT | BUTTON_REL);
options.MENU=(BUTTON_SELECT | BUTTON_REPEAT);
#elif CONFIG_KEYPAD == GIGABEAT_PAD
options.A=BUTTON_VOL_UP;
options.B=BUTTON_VOL_DOWN;
options.START=BUTTON_POWER;
options.SELECT=BUTTON_SELECT;
options.MENU=BUTTON_MENU;
#endif
options.maxskip=4;
options.fps=0;
options.showstats=0;
options.fullscreen=0;
options.sound=1;
}
else
read(fd,&options, sizeof(options));
close(fd);
}
void savesettings(void)
{
int fd;
char optionsave[sizeof(savedir)+sizeof(optionname)];
snprintf(optionsave, sizeof(optionsave), "%s/%s", savedir, optionname);
fd = open(optionsave, O_WRONLY|O_CREAT|O_TRUNC);
write(fd,&options, sizeof(options));
close(fd);
}
/* this is the plugin entry point */
enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
{
PLUGIN_IRAM_INIT(api)
/* if you are using a global api pointer, don't forget to copy it!
otherwise you will get lovely "I04: IllInstr" errors... :-) */
rb = api;
rb->lcd_setfont(0);
rb->lcd_clear_display();
if (!parameter)
{
rb->splash(HZ*3, true, "Play gameboy ROM file! (.gb/.gbc)");
return PLUGIN_OK;
}
audio_bufferbase = audio_bufferpointer
= rb->plugin_get_audio_buffer((int *)&audio_buffer_free);
#if MEM <= 8 && !defined(SIMULATOR)
/* loaded as an overlay plugin, protect from overwriting ourselves */
if ((unsigned)(plugin_start_addr - (unsigned char *)audio_bufferbase)
< audio_buffer_free)
audio_buffer_free = plugin_start_addr - (unsigned char *)audio_bufferbase;
#endif
setoptions();
shut=0;
cleanshut=0;
#ifdef HAVE_WHEEL_POSITION
rb->wheel_send_events(false);
#endif
/* now go ahead and have fun! */
/* rb->splash(HZ*2, true, "Rockboy v0.3"); */
/* rb->lcd_clear_display(); */
gnuboy_main(parameter);
#ifdef HAVE_WHEEL_POSITION
rb->wheel_send_events(true);
#endif
if(shut&&!cleanshut)
{
rb->splash(HZ/2, true, errormsg);
return PLUGIN_ERROR;
}
pcm_close();
rb->splash(HZ/2, true, "Shutting down");
savesettings();
cleanup();
return PLUGIN_OK;
}