diff options
author | Jens Arnold <amiconn@rockbox.org> | 2006-02-23 20:46:33 +0000 |
---|---|---|
committer | Jens Arnold <amiconn@rockbox.org> | 2006-02-23 20:46:33 +0000 |
commit | eeec278d21ae258da9108bbbccf04d977c3d3bfa (patch) | |
tree | bcb651133b076f9adc62f25f72369db32bfdf4f8 /apps/plugins/lib/overlay.c | |
parent | df25cd5376a34898702b173e4d52badc088afa9f (diff) |
Made the overlay loader code part of the plugin library.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@8813 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/lib/overlay.c')
-rwxr-xr-x | apps/plugins/lib/overlay.c | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/apps/plugins/lib/overlay.c b/apps/plugins/lib/overlay.c new file mode 100755 index 0000000000..31c2b00f91 --- /dev/null +++ b/apps/plugins/lib/overlay.c @@ -0,0 +1,106 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Overlay loader + * + * Copyright (C) 2006 Jens Arnold + * + * 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. + * + ****************************************************************************/ + +#ifndef SIMULATOR +#include "plugin.h" + +/* load and run a plugin linked as an overlay. + + arguments: + rb = pointer to plugin api, also passed on to the overlay + parameter = plugin parameter, passed on to the overlay + filename = overlay file name, absolute path as usual + name = overlay display name + + result: + return value from the overlay + + As long as a large plugin to be overlayed doesn't use the audiobuffer + itself, no adjustments in the plugin source code are necessary to make + it work as an overlay, it only needs an adapted linker script. + + If the overlayed plugin *does* use the audiobuffer itself, it needs + to make sure not to overwrite itself. + + The linker script for the overlay should use a base address towards the + end of the audiobuffer, just low enough to make the overlay fit. */ + +enum plugin_status run_overlay(struct plugin_api* rb, void* parameter, + unsigned char *filename, unsigned char *name) +{ + int fd, readsize; + int audiobuf_size; + unsigned char *audiobuf; + static struct plugin_header header; + + fd = rb->open(filename, O_RDONLY); + if (fd < 0) + { + rb->splash(2*HZ, true, "Can't open %s", filename); + return PLUGIN_ERROR; + } + readsize = rb->read(fd, &header, sizeof(header)); + rb->close(fd); + /* Close for now. Less code than doing it in all error checks. + * Would need to seek back anyway. */ + + if (readsize != sizeof(header)) + { + rb->splash(2*HZ, true, "Reading %s overlay failed.", name); + return PLUGIN_ERROR; + } + if (header.magic != PLUGIN_MAGIC || header.target_id != TARGET_ID) + { + rb->splash(2*HZ, true, "%s overlay: Incompatible model.", name); + return PLUGIN_ERROR; + } + if (header.api_version != PLUGIN_API_VERSION) + { + rb->splash(2*HZ, true, "%s overlay: Incompatible version.", name); + return PLUGIN_ERROR; + } + + audiobuf = rb->plugin_get_audio_buffer(&audiobuf_size); + if (header.load_addr < audiobuf || + header.end_addr > audiobuf + audiobuf_size) + { + rb->splash(2*HZ, true, "%s overlay doesn't fit into memory.", name); + return PLUGIN_ERROR; + } + rb->memset(header.load_addr, 0, header.end_addr - header.load_addr); + + fd = rb->open(filename, O_RDONLY); + if (fd < 0) + { + rb->splash(2*HZ, true, "Can't open %s", filename); + return PLUGIN_ERROR; + } + readsize = rb->read(fd, header.load_addr, header.end_addr - header.load_addr); + rb->close(fd); + + if (readsize < 0) + { + rb->splash(2*HZ, true, "Reading %s overlay failed.", name); + return PLUGIN_ERROR; + } + return header.entry_point(rb, parameter); +} +#endif |