Index: tools/buildzip.pl =================================================================== --- tools/buildzip.pl (revision 24733) +++ tools/buildzip.pl (working copy) @@ -221,6 +221,7 @@ mkdir "$rbdir/rocks/apps", 0777; mkdir "$rbdir/rocks/demos", 0777; mkdir "$rbdir/rocks/viewers", 0777; + mkdir "$rbdir/pebbles", 0777; if ($recording) { mkdir "$rbdir/recpresets", 0777; @@ -275,6 +276,7 @@ } find(find_copyfile(qr/\.(rock|ovl|lua)/, abs_path("$rbdir/rocks/")), 'apps/plugins'); + find(find_copyfile(qr/\.(pebble)/, abs_path("$rbdir/pebbles/")), 'apps/pebbles'); open VIEWERS, "$ROOT/apps/plugins/viewers.config" or die "can't open viewers.config"; Index: tools/root.make =================================================================== --- tools/root.make (revision 24733) +++ tools/root.make (working copy) @@ -83,6 +83,9 @@ include $(APPSDIR)/plugins/plugins.make endif + include $(APPSDIR)/pebbles/pebbles.make + + ifdef SIMVER include $(ROOTDIR)/uisimulator/uisimulator.make endif @@ -93,7 +96,7 @@ OBJ += $(BMP:.bmp=.o) OBJ := $(subst $(ROOTDIR),$(BUILDDIR),$(OBJ)) -build: $(TOOLS) $(BUILDDIR)/$(BINARY) $(CODECS) $(ROCKS) $(ARCHOSROM) $(RBINFO) +build: $(TOOLS) $(BUILDDIR)/$(BINARY) $(CODECS) $(ROCKS) $(PEBBLES) $(ARCHOSROM) $(RBINFO) $(RBINFO): $(BUILDDIR)/$(BINARY) $(SILENT)echo Creating $(@F) Index: apps/pebble.h =================================================================== --- apps/pebble.h (revision 0) +++ apps/pebble.h (revision 0) @@ -0,0 +1,54 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2010 Frank Gevaerts + * + * 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 "plugin.h" +#include "viewport.h" +#include "skin_engine/skin_tokens.h" + +struct plugin_api; +#define NUM_PEBBLES 4 + +struct pebble_header +{ + unsigned long magic; + unsigned short target_id; + unsigned short api_version; + + void *(*init)(struct wps_token *token,struct viewport *vp,const struct plugin_api *api); + int (*run)(void *blob,const struct plugin_api *rb); +}; + +int pebble_load(const char* pebble); + +int pebble_run(unsigned short index); +void pebble_init(unsigned short index,struct wps_token *token,struct viewport *vp); + +void pebbles_reset(void); + +void *pebble_start(struct wps_token *token,struct viewport *vp,const struct plugin_api *rb); +int pebble_paint(void *blob,const struct plugin_api *rb); + +#define PEBBLE_HEADER \ + const struct pebble_header __header \ + __attribute__ ((section (".header")))= { \ + PLUGIN_MAGIC, TARGET_ID, PLUGIN_API_VERSION, \ + pebble_start,pebble_paint }; + Index: apps/gui/skin_engine/skin_parser.c =================================================================== --- apps/gui/skin_engine/skin_parser.c (revision 24733) +++ apps/gui/skin_engine/skin_parser.c (working copy) @@ -27,6 +27,7 @@ #include "misc.h" #include "plugin.h" #include "viewport.h" +#include "pebble.h" #ifdef __PCTOOL__ #ifdef WPSEDITOR @@ -143,6 +144,8 @@ return 0; } +static int parse_pebble(const char *wps_bufptr, + struct wps_token *token, struct wps_data *wps_data); #ifdef HAVE_LCD_BITMAP static int parse_viewport_display(const char *wps_bufptr, struct wps_token *token, struct wps_data *wps_data); @@ -379,6 +382,8 @@ { WPS_TOKEN_TRANSLATEDSTRING, "Sx", WPS_REFRESH_STATIC, parse_setting_and_lang }, { WPS_TOKEN_LANG_IS_RTL , "Sr", WPS_REFRESH_STATIC, NULL }, + + { WPS_TOKEN_PEBBLE , "P", WPS_REFRESH_DYNAMIC, parse_pebble }, { WPS_TOKEN_LASTTOUCH, "Tl", WPS_REFRESH_DYNAMIC, parse_timeout }, { WPS_TOKEN_CURRENT_SCREEN, "cs", WPS_REFRESH_DYNAMIC, NULL }, @@ -531,6 +536,36 @@ return true; } +static int parse_pebble(const char *wps_bufptr, + struct wps_token *token, + struct wps_data *wps_data) +{ + (void)wps_data; + const char *ptr = wps_bufptr; + const char *end; + char temp[64]; + char filename[MAX_PATH]; + + /* Find the setting's cfg_name */ + if (*ptr != '|') + return WPS_ERROR_INVALID_PARAM; + ptr++; + end = strchr(ptr,'|'); + if (!end) + return WPS_ERROR_INVALID_PARAM; + strlcpy(temp, ptr,end-ptr+1); + snprintf(filename,MAX_PATH, ROCKBOX_DIR "/pebbles/%s.pebble",temp); + + short index=pebble_load(filename); + if(index<0) + return false; + + pebble_init(index,token,&(curr_vp->vp)); + + token->value.i = index; + return skip_end_of_line(wps_bufptr); +} + #ifdef HAVE_LCD_BITMAP static int parse_statusbar_enable(const char *wps_bufptr, @@ -1935,6 +1970,7 @@ **/ static void skin_data_reset(struct wps_data *wps_data) { + pebbles_reset(); #ifdef HAVE_LCD_BITMAP wps_data->images = NULL; wps_data->progressbars = NULL; Index: apps/gui/skin_engine/skin_display.c =================================================================== --- apps/gui/skin_engine/skin_display.c (revision 24733) +++ apps/gui/skin_engine/skin_display.c (working copy) @@ -37,6 +37,7 @@ #include "screen_access.h" #include "playlist.h" #include "audio.h" +#include "pebble.h" #ifdef HAVE_LCD_BITMAP #include "peakmeter.h" @@ -80,6 +81,11 @@ return retval; } +static void draw_pebble(unsigned short pebble) +{ + pebble_run(pebble); +} + #ifdef HAVE_LCD_BITMAP void skin_statusbar_changed(struct gui_wps *skin) @@ -266,7 +272,6 @@ } } - /* clears the area where the image was shown */ static void clear_image_pos(struct gui_wps *gwps, struct gui_img *img) { @@ -703,6 +708,9 @@ draw_playlist_viewer_list(gwps, data->tokens[i].value.data); break; #endif + case WPS_TOKEN_PEBBLE: + draw_pebble(data->tokens[i].value.i); + break; default: { /* get the value of the tag and copy it to the buffer */ Index: apps/gui/skin_engine/skin_tokens.h =================================================================== --- apps/gui/skin_engine/skin_tokens.h (revision 24733) +++ apps/gui/skin_engine/skin_tokens.h (working copy) @@ -207,6 +207,8 @@ WPS_TOKEN_SETTING, WPS_TOKEN_CURRENT_SCREEN, WPS_TOKEN_LANG_IS_RTL, + + WPS_TOKEN_PEBBLE, /* Recording Tokens */ TOKEN_MARKER_RECORDING, Index: apps/gui/skin_engine/skin_buffer.c =================================================================== --- apps/gui/skin_engine/skin_buffer.c (revision 24733) +++ apps/gui/skin_engine/skin_buffer.c (working copy) @@ -66,8 +66,9 @@ #endif -#define SKIN_BUFFER_SIZE (MAIN_BUFFER + REMOTE_BUFFER) + \ - (WPS_MAX_TOKENS * sizeof(struct wps_token)) +//#define SKIN_BUFFER_SIZE (MAIN_BUFFER + REMOTE_BUFFER) + \ +// (WPS_MAX_TOKENS * sizeof(struct wps_token)) +#define SKIN_BUFFER_SIZE 0x2000 #endif #ifdef HAVE_LCD_CHARCELLS Index: apps/pebbles/SOURCES =================================================================== --- apps/pebbles/SOURCES (revision 0) +++ apps/pebbles/SOURCES (revision 0) @@ -0,0 +1,2 @@ +test_pebble.c +starfield.c Index: apps/pebbles/pebbles.make =================================================================== --- apps/pebbles/pebbles.make (revision 0) +++ apps/pebbles/pebbles.make (revision 0) @@ -0,0 +1,61 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id: pebbles.make 24322 2010-01-24 15:32:23Z funman $ +# + +# single-file pebbles: +PEBBLES_SRC = $(call preprocess, $(APPSDIR)/pebbles/SOURCES) +OTHER_SRC += $(PEBBLES_SRC) +PEBBLES1 := $(PEBBLES_SRC:.c=.pebble) +PEBBLES1 := $(subst $(ROOTDIR),$(BUILDDIR),$(PEBBLES1)) + +PEBBLES := $(PEBBLES1) + +### build data / rules +ifndef SIMVER +CONFIGFILE := $(FIRMDIR)/export/config/$(MODELNAME).h +PEBBLE_LDS := $(APPSDIR)/pebbles/pebble.lds +PEBBLELINK_LDS := $(BUILDDIR)/apps/pebbles/pebble.link +endif + +OTHER_INC += -I$(APPSDIR)/pebbles + +# special compile flags for pebbles: +PEBBLEFLAGS = -I$(APPSDIR)/pebbles -DPEBBLE -fPIC $(CFLAGS) + +# single-file pebbles depend on their respective .o +$(PEBBLES1): $(BUILDDIR)/%.pebble : $(BUILDDIR)/%.o + +# dependency for all pebbles +$(PEBBLES): $(APPSDIR)/pebble.h $(PEBBLELINK_LDS) + +$(PEBBLELINK_LDS): $(PEBBLE_LDS) $(CONFIGFILE) + $(call PRINTS,PP $(@F)) + $(shell mkdir -p $(dir $@)) + $(call preprocess2file,$<,$@,-DLOADADDRESS=$(LOADADDRESS)) + +# special pattern rule for compiling pebbles with extra flags +$(BUILDDIR)/apps/pebbles/%.o: $(ROOTDIR)/apps/pebbles/%.c + $(SILENT)mkdir -p $(dir $@) + $(call PRINTS,CC $(subst $(ROOTDIR)/,,$<))$(CC) -I$(dir $<) $(PEBBLEFLAGS) -c $< -o $@ + +ifdef SIMVER + PEBBLELDFLAGS = $(SHARED_FLAG) # <-- from Makefile +else + PEBBLELDFLAGS = -T$(PEBBLELINK_LDS) -Wl,--gc-sections -Wl,-Map,$*.map +endif + +$(BUILDDIR)/%.pebble: + $(call PRINTS,LD $(@F))$(CC) $(PEBBLEFLAGS) -o $(BUILDDIR)/$*.elf \ + $(filter %.o, $^) \ + $(filter %.a, $+) \ + -lgcc $(PEBBLELDFLAGS) +ifdef SIMVER + $(SILENT)cp $(BUILDDIR)/$*.elf $@ +else + $(SILENT)$(OC) -O binary $(BUILDDIR)/$*.elf $@ +endif Index: apps/pebbles/test_pebble.c =================================================================== --- apps/pebbles/test_pebble.c (revision 0) +++ apps/pebbles/test_pebble.c (revision 0) @@ -0,0 +1,64 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: $ + * + * Copyright (C) 2010 Frank Gevaerts + * + * 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 "pebble.h" + +PEBBLE_HEADER + +void *pebble_start(struct wps_token *token,struct viewport *vp,const struct plugin_api *rb) +{ + (void)token; + (void)rb; + // We only need the viewport, so don't bother doing more complicated things + return vp; +} + +void draw_angled_line(const struct plugin_api *rb,int x,int y,int width,int height,int angle,int length) +{ + const signed char sine_table[] = {0, 10, 20, 30, 40, 49, 58, 66, 74, 80, 86, 91, 95, 97, 99, 100, 99, 97, 95, 91, 86, 80, 74, 66, 58, 49, 40, 30, 20, 10, 0, -10, -20, -30, -40, -50, -58, -66, -74, -80, -86, -91, -95, -97, -99, -100, -99, -97, -95, -91, -86, -80, -74, -66, -58, -50, -40, -30, -20, -10}; + + rb->lcd_drawline(x,y,x+length*width*sine_table[angle/6]/10000, + y-length*height*sine_table[(angle/6+15)%60]/10000); +} + +int pebble_paint(void *blob,const struct plugin_api *rb) +{ + struct viewport *vp=(struct viewport*)blob; + int fg,bg; + + fg=rb->lcd_get_foreground(); + bg=rb->lcd_get_background(); + + rb->lcd_set_foreground(bg); + rb->lcd_fillrect(0,0,vp->width,vp->height); + rb->lcd_set_foreground(fg); + rb->lcd_drawrect(0,0,vp->width,vp->height); + + struct tm *t=rb->get_time(); + + int xc=vp->width/2; + int yc=vp->height/2; + + draw_angled_line(rb,xc,yc,vp->width/2,vp->height/2,6*t->tm_sec,100); + draw_angled_line(rb,xc,yc,vp->width/2,vp->height/2,6*t->tm_min,90); + draw_angled_line(rb,xc,yc,vp->width/2,vp->height/2,30*(t->tm_hour%12)+t->tm_min/12,50); + return 0; +} Index: apps/pebbles/pebble.lds =================================================================== --- apps/pebbles/pebble.lds (revision 0) +++ apps/pebbles/pebble.lds (revision 0) @@ -0,0 +1,77 @@ +#include "config.h" + +/* These output formats should be in the config-files */ + +#ifdef CPU_COLDFIRE +OUTPUT_FORMAT(elf32-m68k) +#elif defined(CPU_ARM) +OUTPUT_FORMAT(elf32-littlearm) +#elif defined(CPU_SH) +OUTPUT_FORMAT(elf32-sh) +#elif defined(CPU_MIPS) +OUTPUT_FORMAT(elf32-littlemips) +#else +/* We can have an #error here we don't use this file when build sims! */ +#error Unknown CPU architecture +#endif + +#define CODE_ORIGIN 0xDEAD0000 +#define CODE_LENGTH 0x2000 + + +MEMORY +{ + PEBBLE_CODE : ORIGIN = CODE_ORIGIN , LENGTH = CODE_LENGTH + PEBBLE_FIRST : ORIGIN = CODE_ORIGIN-12 , LENGTH = 12 +} + +SECTIONS +{ + .first : + { + LONG(ADDR(.got)-CODE_ORIGIN) + LONG(ADDR(.got)+SIZEOF(.got)-CODE_ORIGIN) + LONG(ADDR(.bss)+SIZEOF(.bss)-CODE_ORIGIN) + } > PEBBLE_FIRST + + .header : + { + KEEP(*(.header)) + . = ALIGN(0x4); + } > PEBBLE_CODE + + .got : + { + *(.got) + *(.got.plt) + . = ALIGN(0x4); + } > PEBBLE_CODE + + .text : + { + *(.text*) + . = ALIGN(0x4); + *(.rodata*) + . = ALIGN(0x4); +#ifdef CPU_ARM + *(.glue_7) + *(.glue_7t) +#endif + + } > PEBBLE_CODE + + .bss : + { + *(.data) + *(.bss) + . = ALIGN(0x4); + } > PEBBLE_CODE + + /DISCARD/ : + { + *(.eh_frame) +#ifdef CPU_MIPS + *(.rel.dyn) +#endif + } +} Index: apps/pebbles/starfield.c =================================================================== --- apps/pebbles/starfield.c (revision 0) +++ apps/pebbles/starfield.c (revision 0) @@ -0,0 +1,196 @@ +/*************************************************************************** +* __________ __ ___. +* Open \______ \ ____ ____ | | _\_ |__ _______ ___ +* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +* \/ \/ \/ \/ \/ +* Copyright (C) 2005 Kevin Ferrare +* +* 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 "pebble.h" + +PEBBLE_HEADER + +/******************************* Globals ***********************************/ + +#define LCD_CENTER_X (vp->width/2) +#define LCD_CENTER_Y (vp->height/2) +#define Z_MAX_DIST 100 + + +#define MAX_STARS 100 +#define INIT_STARS 100 +#define INIT_SPACE_SPEED 1 +#define STAR_MAX_VELOCITY 2 +/* + * max 3d coord in the 2d screen : + * example with x + * x2d=x3d/z+LCD_CENTER_X (+LCD_CENTER_X to center ...) + * so + * max_x2d=max_x3d/max_z+LCD_CENTER_X + * max_x3d=(max_x2d-LCD_CENTER_X)*max_z + * with + * max_x2d = LCD_WIDTH + * max_z = Z_MAX_DIST + * we have now + * max_x3d=(LCD_WIDTH-LCD_CENTER_X)*Z_MAX_DIST + * max_x3d=LCD_CENTER_X*Z_MAX_DIST + */ + +#define MAX_INIT_STAR_X LCD_CENTER_X*Z_MAX_DIST +#define MAX_INIT_STAR_Y LCD_CENTER_Y*Z_MAX_DIST + +/* + * Each star's stuffs + */ +struct star +{ + int x,y,z; + int velocity; +#ifdef HAVE_LCD_COLOR + int color; +#endif +}; + +struct starfield +{ + struct star tab[MAX_STARS]; + int nb_stars; + int z_move; +} starfield; + +static void star_init(struct star * star, int z_move, const struct plugin_api *rb,struct viewport *vp) +{ + star->velocity=rb->rand() % STAR_MAX_VELOCITY+1; + /* choose x between -MAX_INIT_STAR_X and MAX_INIT_STAR_X */ + star->x=rb->rand() % (2*MAX_INIT_STAR_X)-MAX_INIT_STAR_X; + star->y=rb->rand() % (2*MAX_INIT_STAR_Y)-MAX_INIT_STAR_Y; +#ifdef HAVE_LCD_COLOR + star->color=LCD_RGBPACK(rb->rand()%128+128,rb->rand()%128+128, + rb->rand()%128+128); +#endif + if(z_move>=0) + star->z=Z_MAX_DIST; + else + star->z=rb->rand() %Z_MAX_DIST/2+1; +} + +static void star_move(struct star * star, int z_move, const struct plugin_api *rb,struct viewport *vp) +{ + star->z -= z_move*star->velocity; + if (star->z <= 0 || star->z > Z_MAX_DIST) + star_init(star, z_move, rb,vp); +} + +static void star_draw(struct star * star, int z_move, const struct plugin_api *rb,struct viewport *vp) +{ + int x_draw, y_draw; + /* + * 3d -> 2d : projection on the screen : x2d=x3d/z (thales theorem) + * we put the star in the center of the screen + */ + x_draw = star->x / star->z + LCD_CENTER_X; + if (x_draw < 1 || x_draw >= LCD_WIDTH) + { + star_init(star, z_move, rb,vp); + return; + } + y_draw = star->y / star->z + LCD_CENTER_Y; + if (y_draw < 1 || y_draw >= LCD_HEIGHT) + { + star_init(star, z_move, rb,vp); + return; + } + +#ifdef HAVE_LCD_COLOR + rb->lcd_set_foreground(star->color); +#endif + + rb->lcd_drawpixel(x_draw, y_draw); + if(star->z<5*Z_MAX_DIST/6) + { + rb->lcd_drawpixel(x_draw, y_draw - 1); + rb->lcd_drawpixel(x_draw - 1, y_draw); + if(star->zlcd_drawpixel(x_draw + 1, y_draw); + rb->lcd_drawpixel(x_draw, y_draw + 1); + } + } +} + +/* + * Whole starfield operations + */ + +static void starfield_init(void) +{ + starfield.nb_stars=0; + starfield.z_move=INIT_SPACE_SPEED; +} + +static void starfield_add_stars( int nb_to_add,const struct plugin_api *rb, + struct viewport *vp) +{ + int i, old_nb_stars; + old_nb_stars=starfield.nb_stars; + starfield.nb_stars+=nb_to_add; + + if(starfield.nb_stars > MAX_STARS) + starfield.nb_stars=MAX_STARS; + + for( i=old_nb_stars ; i < starfield.nb_stars ; ++i ) + { + star_init( &(starfield.tab[i]), starfield.z_move, rb,vp ); + } +} + + +static void starfield_move_and_draw(const struct plugin_api *rb,struct viewport *vp) +{ + int i; + for(i=0;ilcd_get_foreground(); + bg=rb->lcd_get_background(); + + rb->lcd_set_foreground(bg); + rb->lcd_fillrect(0,0,vp->width,vp->height); + rb->lcd_set_foreground(fg); + + + starfield_move_and_draw(rb,vp); + return 0; +} + +/*************************** Plugin entry point ****************************/ + +void *pebble_start(struct wps_token *token,struct viewport *vp,const struct plugin_api *rb) +{ + (void)token; + (void)rb; + starfield_init(); + starfield_add_stars(INIT_STARS,rb,vp); + return vp; +} Index: apps/plugin.c =================================================================== --- apps/plugin.c (revision 24733) +++ apps/plugin.c (working copy) @@ -99,7 +99,7 @@ static int creat_wrapper(const char *pathname); #endif -static const struct plugin_api rockbox_api = { +const struct plugin_api rockbox_api = { /* lcd */ #ifdef HAVE_LCD_CONTRAST Index: apps/SOURCES =================================================================== --- apps/SOURCES (revision 24733) +++ apps/SOURCES (working copy) @@ -39,6 +39,7 @@ playlist_catalog.c playlist_viewer.c plugin.c +pebble.c root_menu.c screens.c settings.c Index: apps/pebble.c =================================================================== --- apps/pebble.c (revision 0) +++ apps/pebble.c (revision 0) @@ -0,0 +1,137 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id: plugin.c 24644 2010-02-14 06:26:16Z jdgordon $ + * + * Copyright (C) 2002 Björn Stenberg + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "config.h" +#include "pebble.h" +#include "plugin.h" +#include "lang.h" +#include "splash.h" +#include "logf.h" +#include "skin_engine/skin_buffer.h" +#include "settings.h" + + +struct pebble_header pebbles[NUM_PEBBLES]; +void * pebble_data[NUM_PEBBLES]; + +int last_pebble=0; +extern const struct plugin_api rockbox_api; + + +int pebble_load(const char* pebble) +{ + int fd; + ssize_t readsize; +#if NUM_CORES > 1 + unsigned my_core; +#endif + struct + { + int got_start; + int got_end; + int load_size; + } meta; + + splash(0, ID2P(LANG_WAIT)); + + fd = open(pebble, O_RDONLY); + if (fd < 0) { + splashf(HZ*2, str(LANG_PLUGIN_CANT_OPEN), pebble); + return fd; + } +#if NUM_CORES > 1 + /* Make sure COP cache is flushed and invalidated before loading */ + my_core = switch_core(CURRENT_CORE ^ 1); + cpucache_invalidate(); + switch_core(my_core); +#endif + + readsize = read(fd, &meta, sizeof(meta)); + if (readsize != sizeof(meta) ) { + splashf(HZ*2, str(LANG_READ_FAILED), pebble); + close(fd); + return -1; + } + + int *buffer=skin_buffer_alloc(meta.load_size); + if(buffer==NULL) + { + splashf(HZ*2, str(LANG_READ_FAILED), pebble); + //FIXME: not the right error + close(fd); + return -1; + } + + readsize = read(fd, buffer, meta.load_size); + close(fd); + + if (readsize < 0) { + splashf(HZ*2, str(LANG_READ_FAILED), pebble); + return -1; + } + + /* Fix GOT */ + + int i; + for(i=meta.got_start/4;iinit-=(0xdead0000-((int)buffer)); + hdr->run-=(0xdead0000-((int)buffer)); + + memcpy(&pebbles[last_pebble], buffer, sizeof(struct pebble_header)); + + /* FIXME: put back version checks */ + + cpucache_invalidate(); + + last_pebble++; + return (last_pebble-1); +} + +void pebbles_reset() +{ + last_pebble=0; +} + +void pebble_init(unsigned short index,struct wps_token *token,struct viewport *vp) +{ + pebble_data[index]=pebbles[index].init(token,vp,&rockbox_api); +} + +int pebble_run(unsigned short index) +{ + return pebbles[index].run(pebble_data[index],&rockbox_api); +}