Index: tools/genlang =================================================================== --- tools/genlang (revision 17684) +++ tools/genlang (working copy) @@ -51,6 +51,9 @@ -i= The target id number, needed for -b. + -k= + The type of language file being generated. 0 = Core, 1 = Plugin + -o Voice mode output. Outputs all id: and voice: lines for the given target! @@ -81,6 +84,8 @@ my $english = $e; my $voiceout = $o; +my $kind = $k; + my $check = ($binary?1:0) + ($prefix?1:0) + ($update?1:0) + ($voiceout?1:0); if($check > 1) { @@ -92,6 +97,11 @@ exit; } +if($kind != 0 && $kind != 1) { + print "Please specify the kind of language file with -k!\n"; + exit; +} + if(($binary || $update || $voiceout) && !$english) { print "Please use -e too when you use -b, -o or -u\n"; exit; @@ -521,6 +531,10 @@ * translated. Use it like str(MACRO) and expect a string to be * returned! */ +MOO + ; + if($kind == 0) { + print HFILE < $(DEPFILE); \ echo "oo" > /dev/null ) Index: tools/buildzip.pl =================================================================== --- tools/buildzip.pl (revision 17684) +++ tools/buildzip.pl (working copy) @@ -199,6 +199,7 @@ } mkdir ".rockbox/langs", 0777; + mkdir ".rockbox/plangs", 0777; mkdir ".rockbox/rocks", 0777; mkdir ".rockbox/rocks/games", 0777; mkdir ".rockbox/rocks/apps", 0777; @@ -391,7 +392,8 @@ system("cp rockbox-info.txt .rockbox/"); # copy the already built lng files - `cp apps/lang/*lng .rockbox/langs/` + system("cp apps/lang/*lng .rockbox/langs/"); + system("cp apps/plugins/lang/*lng .rockbox/plangs/"); } Index: apps/language.c =================================================================== --- apps/language.c (revision 17684) +++ apps/language.c (working copy) @@ -18,9 +18,6 @@ ****************************************************************************/ #include -#if defined(SIMULATOR) && defined(__MINGW32__) -extern int printf(const char *format, ...); -#endif #include "language.h" #include "lang.h" @@ -29,45 +26,47 @@ static unsigned char language_buffer[MAX_LANGUAGE_SIZE]; -void lang_init(void) +void lang_init_helper(unsigned char *src, unsigned char **dest, int count) { - int i; - unsigned char *ptr = (unsigned char *) language_builtin; - - for (i = 0; i < LANG_LAST_INDEX_IN_ARRAY; i++) { - language_strings[i] = ptr; - ptr += strlen((char *)ptr) + 1; /* advance pointer to next string */ + while(count--) { + *dest++ = src; + src += strlen((char *)src) + 1; /* advance pointer to next string */ } } -int lang_load(const char *filename) +void lang_init(void) { - int fsize; + lang_init_helper((unsigned char*)language_builtin, language_strings, + LANG_LAST_INDEX_IN_ARRAY); +} + +int lang_load_helper(const char *filename, const unsigned char *src, + unsigned char **dest, unsigned char *ptr, int max, int size) +{ + int fsize, id; int fd = open(filename, O_RDONLY); int retcode=0; unsigned char lang_header[3]; if(fd < 0) return 1; fsize = filesize(fd) - 2; - if(fsize <= MAX_LANGUAGE_SIZE) { + if(fsize <= size) { read(fd, lang_header, 3); if((lang_header[0] == LANGUAGE_COOKIE) && (lang_header[1] == LANGUAGE_VERSION) && (lang_header[2] == TARGET_ID)) { - read(fd, language_buffer, MAX_LANGUAGE_SIZE); - unsigned char *ptr = language_buffer; - int id; - lang_init(); /* initialize with builtin */ + read(fd, ptr, MAX_LANGUAGE_SIZE); + lang_init_helper((unsigned char*)src, dest, max); /* initialize with builtin */ while(fsize>3) { id = (ptr[0]<<8) | ptr[1]; /* get two-byte id */ ptr+=2; /* pass the id */ - if(id < LANG_LAST_INDEX_IN_ARRAY) { + if(id < max) { #if 0 - printf("%2x New: %30s ", id, ptr); - printf("Replaces: %s\n", language_strings[id]); + DEBUGF("%2x New: %30s ", id, ptr); + DEBUGF("Replaces: %s\n", dest[id]); #endif - language_strings[id] = ptr; /* point to this string */ + dest[id] = ptr; /* point to this string */ } while(*ptr) { /* pass the string */ fsize--; @@ -89,3 +88,9 @@ close(fd); return retcode; } + +int lang_load(const char *filename) +{ + return lang_load_helper(filename, language_builtin, language_strings, language_buffer, + LANG_LAST_INDEX_IN_ARRAY, MAX_LANGUAGE_SIZE); +} Index: apps/language.h =================================================================== --- apps/language.h (revision 17684) +++ apps/language.h (working copy) @@ -23,6 +23,7 @@ MAX_LANGUAGE_SIZE to be the size of the largest currently available language! */ #include "max_language_size.h" +#include "max_plugin_language_size.h" /* both these must match the two initial bytes in the binary lang file */ #define LANGUAGE_COOKIE 0x1a @@ -30,8 +31,11 @@ /* Initialize language array with the builtin strings */ void lang_init(void); +void lang_init_helper(unsigned char *src, unsigned char **dest, int count); /* load a given language file */ int lang_load(const char *filename); +int lang_load_helper(const char *filename, const unsigned char *src, + unsigned char **dest, unsigned char *ptr, int max, int size); #endif Index: apps/Makefile =================================================================== --- apps/Makefile (revision 17684) +++ apps/Makefile (working copy) @@ -225,7 +225,7 @@ $(OBJDIR)/lang.o: lang/$(LANGUAGE).lang $(OBJDIR)/features $(SILENT)for f in `cat $(OBJDIR)/features`; do feat="$$feat:$$f" ; done; \ - perl -s $(TOOLSDIR)/genlang -p=$(BUILDDIR)/lang -t=$(MODELNAME)$$feat $< + perl -s $(TOOLSDIR)/genlang -k=0 -p=$(BUILDDIR)/lang -t=$(MODELNAME)$$feat $< $(call PRINTS,CC lang.c)$(CC) $(CFLAGS) -c $(BUILDDIR)/lang.c -o $@ clean: Index: apps/plugins/lang/espanol.lang =================================================================== --- apps/plugins/lang/espanol.lang (revision 0) +++ apps/plugins/lang/espanol.lang (revision 0) @@ -0,0 +1,437 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# + + + + id: P_LANG_BET + desc: bet text + user: + + *: "Bet" + + + *: "Apuesta" + + + *: "Apuesta" + + + + id: P_LANG_DEALER + desc: dealer text + user: + + *: "Dealer" + + + *: "Banca" + + + *: "Banca" + + + + id: P_LANG_PLAYER + desc: player text + user: + + *: "Player" + + + *: "Jugador" + + + *: "Jugador" + + + + id: P_LANG_TOTAL + desc: total text + user: + + *: "Total" + + + *: "Total" + + + *: "Total" + + + + id: P_LANG_MONEY + desc: money text + user: + + *: "Money" + + + *: "Dinero" + + + *: "Dinero" + + + + id: P_LANG_BUST + desc: player busted + user: + + *: "Bust" + + + *: "Busto" + + + *: "Busto" + + + + id: P_LANG_LOST + desc: blackjack player lost + user: + + *: "Sorry, you lost" + + + *: "Lo siento, perdiste" + + + *: "Lo siento, perdiste" + + + + id: P_LANG_PUSH + desc: blackjack player tied + user: + + *: "Push" + + + *: "Empata" + + + *: "Empata" + + + + id: P_LANG_WON + desc: blackjack player won + user: + + *: "You won" + + + *: "Ganaste" + + + *: "Ganaste" + + + + id: P_LANG_BLACKJACK + desc: blackjack text + user: + + *: "Blackjack" + + + *: "Blackjack" + + + *: "Blackjack" + + + + id: P_LANG_YOU_HAVE + desc: blackjack text that lets user know his total + user: + + *: none + player,recorder,fmrecorder,recorderv2,ondiofm,ondiosp: "You have" + + + *: none + player,recorder,fmrecorder,recorderv2,ondiofm,ondiosp: "Tienes" + + + *: none + player,recorder,fmrecorder,recorderv2,ondiofm,ondiosp: "Tienes" + + + + id: P_LANG_HIGH_SCORE_TITLE + desc: text shown at the top of the high scores screen + user: + + *: "High Scores" + + + *: "Puntajes Altos" + + + *: "Puntajes Altos" + + + + id: P_LANG_NEW_HIGH_SCORE + desc: player ranked in the top high scores + user: + + *: "New high score" + + + *: "Nueva puntaje alto" + + + *: "Nueva puntaje alto" + + + + id: P_LANG_SAVING_HIGH_SCORES + desc: we save the high scores before exiting some plugins + user: + + *: "Saving high scores..." + + + *: "Salvar los puntajes altos..." + + + *: "Salvar los puntajes altos..." + + + + id: P_LANG_SAVING_GAME + desc: the user can save the game + user: + + *: "Saving game..." + + + *: "Salvar el juego" + + + *: "Salvar el juego" + + + + id: P_LANG_BET_INC_SMALL + desc: help text for a small bet increase + user: + + *: "RIGHT: +1" + ipod*: " >>|: +1" + h10: "RIGHT: +1" + + + *: "RIGHT: +1" + ipod*: " >>|: +1" + h10: "RIGHT: +1" + + + *: "RIGHT: +1" + ipod*: " >>|: +1" + h10: "RIGHT: +1" + + + + id: P_LANG_BET_DEC_SMALL + desc: help text for a small bet decrease + user: + + *: "LEFT: -1" + ipod*: " |<<: -1" + h10: "LEFT: -1" + + + *: "LEFT: -1" + ipod*: " |<<: -1" + h10: "LEFT: -1" + + + *: "LEFT: -1" + ipod*: " |<<: -1" + h10: "LEFT: -1" + + + + id: P_LANG_BET_INC_BIG + desc: help text for a large bet increase + user: + + *: "UP: +10" + ipod*,h10: "SCROLL+: +10" + + + *: "UP: +10" + ipod*,h10: "SCROLL+: +10" + + + *: "UP: +10" + ipod*,h10: "SCROLL+: +10" + + + + id: P_LANG_BET_DEC_BIG + desc: help text for a large bet decrease + user: + + *: "DOWN: -10" + ipod*,h10: "SCROLL-: -10" + + + *: "DOWN: -10" + ipod*,h10: "SCROLL-: -10" + + + *: "DOWN: -10" + ipod*,h10: "SCROLL-: -10" + + + + id: P_LANG_DEALER_BLACKJACK + desc: the dealer has a blackjack + user: + + *: "Dealer has blackjack" + + + *: "Banca tiene blackjack" + + + *: "Banca tiene blackjack" + + + + id: P_LANG_DEALER_NO_BLACKJACK + desc: the dealer doesn't have a blackjack + user: + + *: "Dealer does not have blackjack" + + + *: "Banca no tiene blackjack" + + + *: "Banca no tiene blackjack" + + + + id: P_LANG_GET_BET + desc: get the user's bet + user: + + *: "Please enter a bet" + + + *: "Por favor, entrar en una apuesta" + + + *: "Por favor, entrar en una apuesta" + + + + id: P_LANG_SPLIT + desc: used throughout splitting + user: + + *: "Split" + + + *: "Divisi—n" + + + *: "Divisi—n" + + + + id: P_LANG_ASK_SPLIT + desc: split the cards? + user: + + *: "Split?" + + + *: "ĀDividir?" + + + *: "ĀDividir?" + + + + id: P_LANG_BUY_INSURANCE + desc: asking if the user wants to buy insurance + user: + + *: "Buy Insurance?" + + + *: "ĀComprar seguro?" + + + *: "ĀComprar seguro?" + + + + id: P_LANG_HOW_MUCH + desc: how much money does the user want to spend on insurance + user: + + *: "How much?" + + + *: "ĀCu‡nto?" + + + *: "ĀCu‡nto?" + + + + id: P_LANG_NEED_MONEY_DOUBLE_DOWN + desc: player doesn't have enough money to double down + user: + + *: "Not enough money to double down." + + + *: "No suficiente dinero para doblar." + + + *: "No suficiente dinero para doblar." + + + + id: P_LANG_NEED_MONEY_CONTINUE + desc: player doesn't have enough money to keep playing + user: + + *: "Not enough money to continue." + + + *: "No suficiente dinero para seguir." + + + *: "No suficiente dinero para seguir." + + + + id: P_LANG_PLAY_AGAIN + desc: does the user want to keep playing? + user: + + *: "Play again?" + + + *: "ĀJugar otro mano?" + + + *: "ĀJugar otro mano?" + + Index: apps/plugins/lang/SOURCES =================================================================== --- apps/plugins/lang/SOURCES (revision 0) +++ apps/plugins/lang/SOURCES (revision 0) @@ -0,0 +1,2 @@ +english.lang +espanol.lang Index: apps/plugins/lang/english.lang =================================================================== --- apps/plugins/lang/english.lang (revision 0) +++ apps/plugins/lang/english.lang (revision 0) @@ -0,0 +1,437 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# + + + + id: P_LANG_BET + desc: bet text + user: + + *: "Bet" + + + *: "Bet" + + + *: "Bet" + + + + id: P_LANG_DEALER + desc: dealer text + user: + + *: "Dealer" + + + *: "Dealer" + + + *: "Dealer" + + + + id: P_LANG_PLAYER + desc: player text + user: + + *: "Player" + + + *: "Player" + + + *: "Player" + + + + id: P_LANG_TOTAL + desc: total text + user: + + *: "Total" + + + *: "Total" + + + *: "Total" + + + + id: P_LANG_MONEY + desc: money text + user: + + *: "Money" + + + *: "Money" + + + *: "Money" + + + + id: P_LANG_BUST + desc: player busted + user: + + *: "Bust!" + + + *: "Bust!" + + + *: "Bust" + + + + id: P_LANG_LOST + desc: blackjack player lost + user: + + *: "Sorry, you lost." + + + *: "Sorry, you lost." + + + *: "Sorry, you lost" + + + + id: P_LANG_PUSH + desc: blackjack player tied + user: + + *: "Push" + + + *: "Push" + + + *: "Push" + + + + id: P_LANG_WON + desc: blackjack player won + user: + + *: "You won!" + + + *: "You won!" + + + *: "You won" + + + + id: P_LANG_BLACKJACK + desc: blackjack text + user: + + *: "Blackjack" + + + *: "Blackjack" + + + *: "Blackjack" + + + + id: P_LANG_YOU_HAVE + desc: blackjack text that lets user know his total + user: + + *: none + player,recorder,fmrecorder,recorderv2,ondiofm,ondiosp: "You have" + + + *: none + player,recorder,fmrecorder,recorderv2,ondiofm,ondiosp: "You have" + + + *: none + player,recorder,fmrecorder,recorderv2,ondiofm,ondiosp: "You have" + + + + id: P_LANG_HIGH_SCORE_TITLE + desc: text shown at the top of the high scores screen + user: + + *: "High Scores" + + + *: "High Scores" + + + *: "High Scores" + + + + id: P_LANG_NEW_HIGH_SCORE + desc: player ranked in the top high scores + user: + + *: "New high score" + + + *: "New high score" + + + *: "New high score" + + + + id: P_LANG_SAVING_HIGH_SCORES + desc: we save the high scores before exiting some plugins + user: + + *: "Saving high scores..." + + + *: "Saving high scores..." + + + *: "Saving high scores..." + + + + id: P_LANG_SAVING_GAME + desc: the user can save the game + user: + + *: "Saving game..." + + + *: "Saving game..." + + + *: "Saving game..." + + + + id: P_LANG_BET_INC_SMALL + desc: help text for a small bet increase + user: + + *: "RIGHT: +1" + ipod*: " >>|: +1" + h10: "RIGHT: +1" + + + *: "RIGHT: +1" + ipod*: " >>|: +1" + h10: "RIGHT: +1" + + + *: "RIGHT: +1" + ipod*: " >>|: +1" + h10: "RIGHT: +1" + + + + id: P_LANG_BET_DEC_SMALL + desc: help text for a small bet decrease + user: + + *: "LEFT: -1" + ipod*: " |<<: -1" + h10: "LEFT: -1" + + + *: "LEFT: -1" + ipod*: " |<<: -1" + h10: "LEFT: -1" + + + *: "LEFT: -1" + ipod*: " |<<: -1" + h10: "LEFT: -1" + + + + id: P_LANG_BET_INC_BIG + desc: help text for a large bet increase + user: + + *: "UP: +10" + ipod*,h10: "SCROLL+: +10" + + + *: "UP: +10" + ipod*,h10: "SCROLL+: +10" + + + *: "UP: +10" + ipod*,h10: "SCROLL+: +10" + + + + id: P_LANG_BET_DEC_BIG + desc: help text for a large bet decrease + user: + + *: "DOWN: -10" + ipod*,h10: "SCROLL-: -10" + + + *: "DOWN: -10" + ipod*,h10: "SCROLL-: -10" + + + *: "DOWN: -10" + ipod*,h10: "SCROLL-: -10" + + + + id: P_LANG_DEALER_BLACKJACK + desc: the dealer has a blackjack + user: + + *: "Dealer has blackjack" + + + *: "Dealer has blackjack" + + + *: "Dealer has blackjack" + + + + id: P_LANG_DEALER_NO_BLACKJACK + desc: the dealer doesn't have a blackjack + user: + + *: "Dealer does not have blackjack" + + + *: "Dealer does not have blackjack" + + + *: "Dealer does not have blackjack" + + + + id: P_LANG_GET_BET + desc: get the user's bet + user: + + *: "Please enter a bet" + + + *: "Please enter a bet" + + + *: "Please enter a bet" + + + + id: P_LANG_SPLIT + desc: used throughout splitting + user: + + *: "Split" + + + *: "Split" + + + *: "Split" + + + + id: P_LANG_ASK_SPLIT + desc: split the cards? + user: + + *: "Split?" + + + *: "Split?" + + + *: "Split?" + + + + id: P_LANG_BUY_INSURANCE + desc: asking if the user wants to buy insurance + user: + + *: "Buy Insurance?" + + + *: "Buy Insurance?" + + + *: "Buy Insurance?" + + + + id: P_LANG_HOW_MUCH + desc: how much money does the user want to spend on insurance + user: + + *: "How much?" + + + *: "How much?" + + + *: "How much?" + + + + id: P_LANG_NEED_MONEY_DOUBLE_DOWN + desc: player doesn't have enough money to double down + user: + + *: "Not enough money to double down." + + + *: "Not enough money to double down." + + + *: "Not enough money to double down." + + + + id: P_LANG_NEED_MONEY_CONTINUE + desc: player doesn't have enough money to keep playing + user: + + *: "Not enough money to continue." + + + *: "Not enough money to continue." + + + *: "Not enough money to continue." + + + + id: P_LANG_PLAY_AGAIN + desc: does the user want to keep playing? + user: + + *: "Play again?" + + + *: "Play again?" + + + *: "Play again?" + + Index: apps/plugins/lang/Makefile =================================================================== --- apps/plugins/lang/Makefile (revision 0) +++ apps/plugins/lang/Makefile (revision 0) @@ -0,0 +1,40 @@ +# __________ __ ___. +# Open \______ \ ____ ____ | | _\_ |__ _______ ___ +# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / +# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < +# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ +# \/ \/ \/ \/ \/ +# $Id$ +# + +INCLUDES= $(TARGET_INC) -I$(FIRMDIR)/include -I$(FIRMDIR)/export \ +-I. -I$(BUILDDIR) -I$(OBJDIR) + +# the header we generate +HEADER = $(BUILDDIR)/max_plugin_language_size.h + +# This sets up 'SRC' based on the files mentioned in SOURCES +include $(TOOLSDIR)/makesrc.inc +SOURCES=$(SRC) + +# OUTP is the list of files to depend upon +OUTP = $(patsubst %.lang,$(OBJDIR)/%.lng, $(SOURCES)) + +# the generated file with features specified genlang-style +FEATS=$(BUILDDIR)/apps/genlang-features + +ifndef V +SILENT=@ +endif +PRINTS=$(SILENT)$(call info,$(1)) + +all: $(HEADER) + +# generic rule for creating .lng from .lang +$(OBJDIR)/%.lng : %.lang + $(call PRINTS,PLUGIN GENLANG $<) + $(SILENT)$(TOOLSDIR)/genlang -e=$(APPSDIR)/plugins/lang/english.lang -t=$(MODELNAME) -i=$(TARGET_ID) -b=$@ $< + +$(HEADER): $(OUTP) + $(call PRINTS,Make $(HEADER)) + $(SILENT)echo "#define MAX_PLUGIN_LANGUAGE_SIZE `ls -ln $(OBJDIR)/* | awk '{print $$5}' | sort -n | tail -1`" > $(HEADER) Index: apps/plugins/lib/pluginlib_lang.c =================================================================== --- apps/plugins/lib/pluginlib_lang.c (revision 0) +++ apps/plugins/lib/pluginlib_lang.c (revision 0) @@ -0,0 +1,54 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Tom Ross + * + * 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 "language.h" +#include "pluginlib_lang.h" + +static unsigned char *plugin_language_buffer; +static unsigned char **plugin_language_strings; + +void plugin_use_lang(const struct plugin_api* rb) +{ + char buf[64]; + size_t size; + size_t langsize = MAX_PLUGIN_LANGUAGE_SIZE; + + if(langsize & 3) + langsize += (4 - (langsize & 3)); + + plugin_language_buffer = (unsigned char*)rb->plugin_get_buffer(&size); + plugin_language_strings = (unsigned char **)(plugin_language_buffer + + langsize); + rb->lang_init_helper((unsigned char*)plugin_language_builtin, plugin_language_strings, + P_LANG_LAST_INDEX_IN_ARRAY); + + if ( rb->global_settings->lang_file[0]) { + rb->snprintf(buf, sizeof buf, PLUGIN_LANG_DIR "/%s.lng", + rb->global_settings->lang_file); + rb->lang_load_helper(buf, plugin_language_builtin, plugin_language_strings, + plugin_language_buffer, P_LANG_LAST_INDEX_IN_ARRAY, + MAX_PLUGIN_LANGUAGE_SIZE); + } +} + +char* get_plugin_str(int x) +{ + return plugin_language_strings[x]; +} Index: apps/plugins/lib/pluginlib_lang.h =================================================================== --- apps/plugins/lib/pluginlib_lang.h (revision 0) +++ apps/plugins/lib/pluginlib_lang.h (revision 0) @@ -0,0 +1,32 @@ +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2008 by Tom Ross + * + * 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 _LIB_LANG_H_ +#define _LIB_LANG_H_ + +#include "plugin.h" +#include "lang.h" +#include "lang_plugin.h" + +#undef str +#define str(x) rb->language_strings[x] +#define p_str(x) get_plugin_str(x) + +void plugin_use_lang(const struct plugin_api* rb); +char* get_plugin_str(int x); +#endif /* _LIB_LANG_H_ */ Index: apps/plugins/lib/Makefile =================================================================== --- apps/plugins/lib/Makefile (revision 17684) +++ apps/plugins/lib/Makefile (working copy) @@ -29,7 +29,7 @@ include $(TOOLSDIR)/makesrc.inc SOURCES = $(SRC) -OBJS2 := $(SRC:%.c=$(OBJDIR)/%.o) +OBJS2 := $(SRC:%.c=$(OBJDIR)/%.o) $(OBJDIR)/lang_plugin.o OBJS = $(patsubst %.S, $(OBJDIR)/%.o, $(OBJS2)) DEPFILE = $(OBJDIR)/dep-pluginlib DIRS = . @@ -42,6 +42,10 @@ $(call PRINTS,AR+RANLIB $(@F))$(AR) ruv $@ $+ >/dev/null 2>&1 $(SILENT)$(RANLIB) $@ +$(OBJDIR)/lang_plugin.o: $(APPSDIR)/plugins/lang/$(LANGUAGE).lang + $(SILENT)perl -s $(TOOLSDIR)/genlang -k=1 -p=$(BUILDDIR)/lang_plugin -t=$(MODELNAME) $< + $(call PRINTS,CC lang_plugin.c)$(CC) $(CFLAGS) -c $(BUILDDIR)/lang_plugin.c -o $@ + include $(TOOLSDIR)/make.inc clean: Index: apps/plugins/lib/SOURCES =================================================================== --- apps/plugins/lib/SOURCES (revision 17684) +++ apps/plugins/lib/SOURCES (working copy) @@ -39,3 +39,4 @@ #endif pluginlib_actions.c helper.c +pluginlib_lang.c Index: apps/plugins/blackjack.c =================================================================== --- apps/plugins/blackjack.c (revision 17684) +++ apps/plugins/blackjack.c (working copy) @@ -5,7 +5,7 @@ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ * \/ \/ \/ \/ \/ - * $Id: $ + * $Id$ * * Copyright (C) 2006 Tom Ross * @@ -18,6 +18,7 @@ ****************************************************************************/ #include "plugin.h" +#include "pluginlib_lang.h" #include "card_deck.h" #include "card_back.h" @@ -348,6 +349,13 @@ bool dirty; } game_context; +/*char * p_str(int x) +{ + static int i=0; + DEBUGF("%d:\t %d %s\n", i, x, rb->plugin_language_strings[x]); + i++; + return rb->plugin_language_strings[x]; +}*/ /***************************************************************************** * blackjack_init() initializes blackjack data structures. ******************************************************************************/ @@ -381,32 +389,34 @@ ******************************************************************************/ static void blackjack_drawtable(struct game_context* bj) { unsigned int w, h, y_loc; - char str[10]; + char str[64]; #if LCD_HEIGHT <= 64 - rb->lcd_getstringsize("Bet", &w, &h); - rb->lcd_putsxy(LCD_WIDTH - w, 2*h + 1, "Bet"); + rb->snprintf(str, sizeof(str), "%s", p_str(P_LANG_BET)); + rb->lcd_getstringsize(str, &w, &h); + rb->lcd_putsxy(LCD_WIDTH - w, 2*h + 1, str); rb->snprintf(str, 9, "$%d", bj->current_bet); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, 3*h + 1, str); y_loc = LCD_HEIGHT/2; #else - rb->lcd_getstringsize("Bet", &w, &h); - rb->lcd_putsxy(LCD_WIDTH - w, 5*h / 2, "Bet"); + rb->snprintf(str, sizeof(str), "%s", p_str(P_LANG_BET)); + rb->lcd_getstringsize(str, &w, &h); + rb->lcd_putsxy(LCD_WIDTH - w, 5*h / 2, str); rb->snprintf(str, 9, "$%d", bj->current_bet); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, 7*h / 2, str); rb->lcd_hline(0, LCD_WIDTH, LCD_HEIGHT/2); y_loc = LCD_HEIGHT/2 + h; #endif - - rb->lcd_putsxy(0,0, "Dealer"); - rb->lcd_getstringsize("Player", &w, &h); - rb->lcd_putsxy(0, y_loc, "Player"); - rb->lcd_getstringsize("Total", &w, &h); - rb->lcd_putsxy(LCD_WIDTH - w, y_loc, "Total"); - rb->lcd_getstringsize("Money", &w, &h); - rb->lcd_putsxy(LCD_WIDTH - w, 0, "Money"); + rb->lcd_putsxy(0, 0, p_str(P_LANG_DEALER)); + rb->lcd_putsxy(0, y_loc, p_str(P_LANG_PLAYER)); + rb->snprintf(str, sizeof(str), "%s", p_str(P_LANG_TOTAL)); + rb->lcd_getstringsize(str, &w, &h); + rb->lcd_putsxy(LCD_WIDTH - w, y_loc, str); + rb->snprintf(str, sizeof(str), "%s", p_str(P_LANG_MONEY)); + rb->lcd_getstringsize(str, &w, &h); + rb->lcd_putsxy(LCD_WIDTH - w, 0, str); rb->snprintf(str, 9, "$%d", bj->player_money - bj->current_bet); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy(LCD_WIDTH - w, h + 1, str); @@ -634,7 +644,7 @@ ******************************************************************************/ static void finish_game(struct game_context* bj) { unsigned int rValue, w, h; - char str[19]; + char str[64]; do { finish_dealer(bj); @@ -644,22 +654,22 @@ rValue = check_totals(bj); if (rValue == 0) { - rb->snprintf(str, sizeof(str), " Bust! "); + rb->snprintf(str, sizeof(str), " %s ", p_str(P_LANG_BUST)); bj->player_money -= bj->current_bet; } else if (rValue == 1) { - rb->snprintf(str, sizeof(str), " Sorry, you lost. "); + rb->snprintf(str, sizeof(str), " %s ", p_str(P_LANG_LOST)); bj->player_money -= bj->current_bet; } else if (rValue == 2) { - rb->snprintf(str, sizeof(str), " Push "); + rb->snprintf(str, sizeof(str), " %s ", p_str(P_LANG_PUSH)); } else if (rValue == 3) { - rb->snprintf(str, sizeof(str), " You won! "); + rb->snprintf(str, sizeof(str), " %s ", p_str(P_LANG_WON)); bj->player_money+= bj->current_bet; } else { - rb->snprintf(str, sizeof(str), " Blackjack! "); + rb->snprintf(str, sizeof(str), " %s! ", p_str(P_LANG_BLACKJACK)); bj->player_money += bj->current_bet * 3 / 2; } rb->lcd_getstringsize(str, &w, &h); @@ -669,7 +679,7 @@ rb->lcd_fillrect(0, LCD_HEIGHT/2, LCD_WIDTH, LCD_HEIGHT/2); rb->lcd_set_drawmode(DRMODE_SOLID); rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + h, str); - rb->snprintf(str, 12, "You have %d", bj->player_total); + rb->snprintf(str, sizeof(str), "%s %d", p_str(P_LANG_YOU_HAVE), bj->player_total); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2, str); #else @@ -816,7 +826,7 @@ static void blackjack_callback(void* param) { struct game_context* bj = (struct game_context*) param; if(bj->dirty) { - rb->splash(HZ, "Saving high scores..."); + rb->splash(HZ, p_str(P_LANG_SAVING_HIGH_SCORES)); blackjack_savescores(bj); } } @@ -824,40 +834,40 @@ /***************************************************************************** * blackjack_get_yes_no() gets a yes/no answer from the user ******************************************************************************/ -static unsigned int blackjack_get_yes_no(char message[20]) { +static unsigned int blackjack_get_yes_no(const char *message) { int button; - unsigned int w, h, b, choice = 0; + unsigned int w1, w2, h, b, choice = 0; bool breakout = false; - char message_yes[24], message_no[24]; - - rb->strcpy(message_yes, message); - rb->strcpy(message_no, message); - rb->strcat(message_yes, " Yes"); - rb->strcat(message_no, " No"); - rb->lcd_getstringsize(message_yes, &w, &h); + char message_yes[64], message_no[64]; const char *stg[] = {message_yes, message_no}; - + + rb->snprintf(message_yes, sizeof(message_yes), "%s %s", message, str(LANG_SET_BOOL_YES)); + rb->snprintf(message_no, sizeof(message_no), "%s %s", message, str(LANG_SET_BOOL_NO)); + rb->lcd_getstringsize(message_yes, &w1, &h); + rb->lcd_getstringsize(message_no, &w2, &h); + w1 = MAX(w1, w2); + #if LCD_HEIGHT <= 64 b = 2*h+1; #else b = h-1; #endif + + while(!breakout) { #ifdef HAVE_LCD_COLOR - rb->lcd_fillrect(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b, w+1, h+3); - rb->lcd_set_foreground(LCD_BLACK); - rb->lcd_set_background(LCD_WHITE); + rb->lcd_fillrect(LCD_WIDTH/2 - w1/2, LCD_HEIGHT/2 + b, w1+1, h+3); + rb->lcd_set_foreground(LCD_BLACK); + rb->lcd_set_background(LCD_WHITE); #else - rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); - rb->lcd_fillrect(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b, w+1, h+3); - rb->lcd_set_drawmode(DRMODE_SOLID); + rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); + rb->lcd_fillrect(LCD_WIDTH/2 - w1/2, LCD_HEIGHT/2 + b, w1+1, h+3); + rb->lcd_set_drawmode(DRMODE_SOLID); #endif - rb->lcd_drawrect(LCD_WIDTH/2 - w/2 - 1, LCD_HEIGHT/2 + b - 1, w+3, h+4); - - while(!breakout) { - rb->lcd_putsxy(LCD_WIDTH/2 - w/2, LCD_HEIGHT/2 + b +1, stg[choice]); - rb->lcd_update_rect(LCD_WIDTH/2 - w/2 - 1, LCD_HEIGHT/2 + b -1, - w+3, h+4); + rb->lcd_drawrect(LCD_WIDTH/2 - w1/2 - 1, LCD_HEIGHT/2 + b - 1, w1+3, h+4); + rb->lcd_putsxy(LCD_WIDTH/2 - w1/2, LCD_HEIGHT/2 + b +1, stg[choice]); + rb->lcd_update_rect(LCD_WIDTH/2 - w1/2 - 1, LCD_HEIGHT/2 + b -1, + w1+3, h+4); button = rb->button_get(true); switch(button) { @@ -873,19 +883,19 @@ choice = BJ_QUIT; break; } - } - #if LCD_DEPTH > 1 - rb->lcd_set_foreground(FG_COLOR); - rb->lcd_set_background(BG_COLOR); + rb->lcd_set_foreground(FG_COLOR); + rb->lcd_set_background(BG_COLOR); #endif + } + return choice; } /***************************************************************************** * blackjack_get_amount() gets an amount from the player to be used ******************************************************************************/ -static signed int blackjack_get_amount(char message[20], signed int lower_limit, +static signed int blackjack_get_amount(const char *message, signed int lower_limit, signed int upper_limit, signed int start) { int button; @@ -894,7 +904,7 @@ unsigned int w, h; signed int amount; - rb->lcd_getstringsize("A", &w, &h); /* find the size of one character */ + rb->lcd_getstringsize(message, &w, &h); if (start > upper_limit) amount = upper_limit; @@ -913,42 +923,28 @@ rb->lcd_puts(0, 1, message); rb->snprintf(str, 9, "$%d", amount); rb->lcd_puts(0, 2, str); - rb->lcd_puts(0, 3, "RIGHT: +1"); - rb->lcd_puts(0, 4, "LEFT: -1"); - rb->lcd_puts(0, 5, "UP: +10"); - rb->lcd_puts(0, 6, "DOWN: -10"); + rb->lcd_puts(0, 3, p_str(P_LANG_BET_INC_SMALL)); + rb->lcd_puts(0, 4, p_str(P_LANG_BET_DEC_SMALL)); + rb->lcd_puts(0, 5, p_str(P_LANG_BET_INC_BIG)); + rb->lcd_puts(0, 6, p_str(P_LANG_BET_DEC_BIG)); rb->lcd_update(); #else rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); - rb->lcd_fillrect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3, 37*w / 2, + rb->lcd_fillrect(LCD_WIDTH/2 - w / 2 - 1, LCD_HEIGHT/2 - 4*h - 3, w+3, 8*h -3); rb->lcd_set_drawmode(DRMODE_SOLID); - rb->lcd_drawrect(LCD_WIDTH/2 - 9*w - 1, LCD_HEIGHT/2 - 4*h - 3, 37*w / 2, + rb->lcd_drawrect(LCD_WIDTH/2 - w / 2 - 1, LCD_HEIGHT/2 - 4*h - 3, w+3, 8*h -3); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 4*h - 1, message); + rb->lcd_putsxy(LCD_WIDTH/2 - w / 2, LCD_HEIGHT/2 - 4*h - 1, message); rb->snprintf(str, 9, "$%d", amount); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, str); -#if (CONFIG_KEYPAD == IPOD_4G_PAD) || \ - (CONFIG_KEYPAD == IPOD_3G_PAD) || \ - (CONFIG_KEYPAD == IPOD_1G2G_PAD) - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, " >>|: +1"); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, " |<<: -1"); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10"); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "SCROLL-: -10"); -#elif CONFIG_KEYPAD == IRIVER_H10_PAD - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, "RIGHT: +1"); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, "LEFT: -1"); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "SCROLL+: +10"); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "SCROLL-: -10"); -#else - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - h-2, "RIGHT: +1"); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 1, "LEFT: -1"); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + h, "UP: +10"); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 + 2*h + 1, "DOWN: -10"); + rb->lcd_putsxy(LCD_WIDTH/2 - w / 2, LCD_HEIGHT/2 - 3*h, str); + rb->lcd_putsxy(LCD_WIDTH/2 - w / 2, LCD_HEIGHT/2 - h-2, p_str(P_LANG_BET_INC_SMALL)); + rb->lcd_putsxy(LCD_WIDTH/2 - w / 2, LCD_HEIGHT/2 - 1, p_str(P_LANG_BET_DEC_SMALL)); + rb->lcd_putsxy(LCD_WIDTH/2 - w / 2, LCD_HEIGHT/2 + h, p_str(P_LANG_BET_INC_BIG)); + rb->lcd_putsxy(LCD_WIDTH/2 - w / 2, LCD_HEIGHT/2 + 2*h + 1, p_str(P_LANG_BET_DEC_BIG)); + rb->lcd_update_rect(LCD_WIDTH/2 - w / 2 - 2, LCD_HEIGHT/2 - 9*h/2, w+2, 8*h-2); + rb->lcd_update(); #endif - rb->lcd_update_rect(LCD_WIDTH/2 - 9*w - 2, LCD_HEIGHT/2 - 9*h/2, 37*w/2 + 1, - 8*h-2); -#endif while(true) { button = rb->button_get(true); @@ -1008,10 +1004,10 @@ rb->lcd_update(); #else rb->lcd_set_drawmode(DRMODE_BG+DRMODE_INVERSEVID); - rb->lcd_fillrect(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, 5*w, h); + rb->lcd_fillrect(LCD_WIDTH/2 - w / 2, LCD_HEIGHT/2 - 3*h, w, h); rb->lcd_set_drawmode(DRMODE_SOLID); - rb->lcd_putsxy(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, str); - rb->lcd_update_rect(LCD_WIDTH/2 - 9*w, LCD_HEIGHT/2 - 3*h, 5*w, h); + rb->lcd_putsxy(LCD_WIDTH/2 - w / 2, LCD_HEIGHT/2 - 3*h, str); + rb->lcd_update_rect(LCD_WIDTH/2 - w / 2, LCD_HEIGHT/2 - 3*h, w, h); #endif changed = false; } @@ -1022,7 +1018,7 @@ * blackjack_get_bet() gets the player's bet. ******************************************************************************/ static void blackjack_get_bet(struct game_context* bj) { - bj->current_bet = blackjack_get_amount("Please enter a bet", 10, + bj->current_bet = blackjack_get_amount(p_str(P_LANG_GET_BET), 10, bj->player_money, bj->current_bet); } @@ -1042,7 +1038,7 @@ * means a split has already occurred and the first hand is done. ******************************************************************************/ static void split(struct game_context* bj) { - if (blackjack_get_yes_no("Split?") == 1) + if (blackjack_get_yes_no(p_str(P_LANG_ASK_SPLIT)) == 1) bj->split_status = 1; else { bj->split_status = 2; @@ -1060,13 +1056,13 @@ static unsigned int insurance(struct game_context* bj) { unsigned int insurance, max_amount; - insurance = blackjack_get_yes_no("Buy Insurance?"); + insurance = blackjack_get_yes_no(p_str(P_LANG_BUY_INSURANCE)); bj->asked_insurance = true; max_amount = bj->current_bet < (unsigned int)bj->player_money ? bj->current_bet/2 : (unsigned int)bj->player_money; if (insurance == 1) return 0; - insurance = blackjack_get_amount("How much?", 0, max_amount, 0); + insurance = blackjack_get_amount(p_str(P_LANG_HOW_MUCH), 0, max_amount, 0); redraw_board(bj); return insurance; } @@ -1075,7 +1071,7 @@ * play_again() checks to see if the player wants to keep playing. ******************************************************************************/ static unsigned int play_again(void) { - return blackjack_get_yes_no("Play Again?"); + return blackjack_get_yes_no(p_str(P_LANG_PLAY_AGAIN)); } /***************************************************************************** @@ -1083,8 +1079,7 @@ ******************************************************************************/ static unsigned int blackjack_menu(struct game_context* bj) { int button; - char *title = "Blackjack"; - char str[18]; + char str[64]; unsigned int i, w, h; bool breakout = false; bool showscores = false; @@ -1098,8 +1093,9 @@ if(!showscores) { /* welcome screen to display key bindings */ - rb->lcd_getstringsize(title, &w, &h); - rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, title); + rb->snprintf(str, sizeof(str), "%s", p_str(P_LANG_BLACKJACK)); + rb->lcd_getstringsize(str, &w, &h); + rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, str); #if CONFIG_KEYPAD == RECORDER_PAD rb->lcd_puts(0, 1, "ON: start"); @@ -1232,13 +1228,13 @@ rb->lcd_puts(0, 4, "LCD BOTTOMRIGHT to save/resume"); #endif } else { - rb->snprintf(str, 12, "%s", "High Scores"); + rb->snprintf(str, sizeof(str), "%s", p_str(P_LANG_HIGH_SCORE_TITLE)); rb->lcd_getstringsize(str, &w, &h); rb->lcd_putsxy((LCD_WIDTH-w)/2, 0, str); /* print high scores */ for(i=0; isnprintf(str, 14, "#%02d: $%d", i+1, bj->highscores[i]); + rb->snprintf(str, sizeof(str), "#%02d: $%d", i+1, bj->highscores[i]); rb->lcd_puts(0, i+1, str); } } @@ -1262,9 +1258,9 @@ case BJACK_RESUME:/* resume game */ if(!blackjack_loadgame(bj)) { - rb->splash(HZ*2, "Nothing to resume"); + rb->splash(HZ*2, ID2P(LANG_NOTHING_TO_RESUME)); } else { - rb->splash(HZ*2, "Loading..."); + rb->splash(HZ*2, ID2P(LANG_WAIT)); breakout = true; } break; @@ -1293,6 +1289,7 @@ int button; unsigned int w, h, temp_var, done = 0, todo = 1; signed int temp; + char buf[64]; bool breakout = false; bool dbl_down = false; @@ -1356,7 +1353,7 @@ !bj->asked_insurance) { temp_var = insurance(bj); if (bj->dealer_total == 21) { - rb->splash(HZ, "Dealer has blackjack"); + rb->splash(HZ, p_str(P_LANG_DEALER_BLACKJACK)); bj->player_money += temp_var; bj->end_hand = true; breakout = true; @@ -1364,7 +1361,7 @@ finish_game(bj); } else { - rb->splash(HZ, "Dealer does not have blackjack"); + rb->splash(HZ, p_str(P_LANG_DEALER_NO_BLACKJACK)); bj->player_money -= temp_var; breakout = true; redraw_board(bj); @@ -1423,13 +1420,13 @@ } } else if((signed int)bj->current_bet * 2 > bj->player_money) { - rb->splash(HZ, "Not enough money to double down."); + rb->splash(HZ, p_str(P_LANG_NEED_MONEY_DOUBLE_DOWN)); redraw_board(bj); rb->lcd_update(); } break; case BJACK_RESUME: /* save and end game */ - rb->splash(HZ, "Saving game..."); + rb->splash(HZ, p_str(P_LANG_SAVING_GAME)); blackjack_savegame(bj); /* fall through to BJACK_QUIT */ @@ -1461,20 +1458,18 @@ bj->player_total = temp_var; temp_var = temp; finish_game(bj); - rb->lcd_getstringsize(" Split 1 ", &w, &h); - rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, - " Split 1 "); - rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, - w,h); + rb->snprintf(buf, sizeof(buf), " %s 1 ", p_str(P_LANG_SPLIT)); + rb->lcd_getstringsize(buf, &w, &h); + rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, buf); bj->current_bet /= 2; rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, w,h); rb->sleep(HZ*2); bj->player_total = temp_var; finish_game(bj); - rb->lcd_getstringsize(" Split 2 ", &w, &h); - rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, - " Split 2 "); + rb->snprintf(buf, sizeof(buf), " %s 2 ", p_str(P_LANG_SPLIT)); + rb->lcd_getstringsize(buf, &w, &h); + rb->lcd_putsxy(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, buf); rb->lcd_update_rect(LCD_WIDTH/2-w/2, LCD_HEIGHT/2-3*h/2, w,h); rb->sleep(HZ*2); @@ -1534,10 +1529,11 @@ struct game_context bj; bool exit = false; unsigned int position; - char str[19]; + char str[64]; (void)parameter; rb = api; + plugin_use_lang(rb); #if LCD_DEPTH > 1 rb->lcd_set_backdrop(NULL); @@ -1551,13 +1547,13 @@ while(!exit) { switch(blackjack(&bj)){ case BJ_LOSE: - rb->splash(HZ, "Not enough money to continue"); + rb->splash(HZ, p_str(P_LANG_NEED_MONEY_CONTINUE)); /* fall through to BJ_END */ case BJ_END: if(!bj.resume) { if((position = blackjack_recordscore(&bj))) { - rb->snprintf(str, 19, "New high score #%d!", position); + rb->snprintf(str, sizeof(str), "%s #%d!", p_str(P_LANG_NEW_HIGH_SCORE), position); rb->splash(HZ*2, str); } } @@ -1569,7 +1565,7 @@ case BJ_QUIT: if(bj.dirty) { - rb->splash(HZ, "Saving high scores..."); + rb->splash(HZ, p_str(P_LANG_SAVING_HIGH_SCORES)); blackjack_savescores(&bj); } exit = true; Index: apps/settings.h =================================================================== --- apps/settings.h (revision 17684) +++ apps/settings.h (working copy) @@ -63,6 +63,7 @@ #define ICON_DIR ROCKBOX_DIR "/icons" #define PLUGIN_DIR ROCKBOX_DIR "/rocks" +#define PLUGIN_LANG_DIR ROCKBOX_DIR "/plangs" #define PLUGIN_GAMES_DIR PLUGIN_DIR "/games" #define PLUGIN_APPS_DIR PLUGIN_DIR "/apps" #define PLUGIN_DEMOS_DIR PLUGIN_DIR "/demos" Index: apps/plugin.c =================================================================== --- apps/plugin.c (revision 17684) +++ apps/plugin.c (working copy) @@ -35,6 +35,7 @@ #include "logf.h" #include "option_select.h" #include "talk.h" +#include "language.h" #if CONFIG_CHARGING #include "power.h" @@ -60,8 +61,7 @@ #endif /* for actual plugins only, not for codecs */ -static bool plugin_loaded = false; -static int plugin_size = 0; +static int plugin_used_buffer = 0; static bool (*pfn_tsr_exit)(bool reenter) = NULL; /* TSR exit callback */ static char current_plugin[MAX_PATH]; @@ -605,6 +605,13 @@ lcd_set_enable_hook, &button_queue, #endif + + lang_init_helper, + lang_load_helper, + &language_strings[0], +#ifdef SIMULATOR + &vp_dummy[0], +#endif }; int plugin_load(const char* plugin, const void* parameter) @@ -637,7 +644,7 @@ return PLUGIN_OK; } pfn_tsr_exit = NULL; - plugin_loaded = false; + plugin_used_buffer = 0; } gui_syncsplash(0, ID2P(LANG_WAIT)); @@ -697,15 +704,13 @@ gui_syncsplash(HZ*2, str(LANG_PLUGIN_WRONG_VERSION)); return -1; } - plugin_size = hdr->end_addr - pluginbuf; + plugin_used_buffer = hdr->end_addr - pluginbuf; /* zero out bss area only, above guards end of pluginbuf */ - if (plugin_size > readsize) - memset(pluginbuf + readsize, 0, plugin_size - readsize); + if (plugin_used_buffer > readsize) + memset(pluginbuf + readsize, 0, plugin_used_buffer - readsize); #endif - plugin_loaded = true; - xm = lcd_getxmargin(); ym = lcd_getymargin(); lcd_setmargins(0,0); @@ -766,7 +771,7 @@ #endif if (pfn_tsr_exit == NULL) - plugin_loaded = false; + plugin_used_buffer = 0; sim_plugin_close(pd); @@ -788,23 +793,11 @@ being used. If no plugin is loaded, returns the entire plugin buffer */ void* plugin_get_buffer(size_t *buffer_size) { - int buffer_pos; - - if (plugin_loaded) - { - if (plugin_size >= PLUGIN_BUFFER_SIZE) - return NULL; - - *buffer_size = PLUGIN_BUFFER_SIZE-plugin_size; - buffer_pos = plugin_size; - } - else - { - *buffer_size = PLUGIN_BUFFER_SIZE; - buffer_pos = 0; - } - - return &pluginbuf[buffer_pos]; + if(plugin_used_buffer >= PLUGIN_BUFFER_SIZE) + return NULL; + + *buffer_size = PLUGIN_BUFFER_SIZE - plugin_used_buffer; + return &pluginbuf[plugin_used_buffer]; } /* Returns a pointer to the mp3 buffer. Index: apps/plugin.h =================================================================== --- apps/plugin.h (revision 17684) +++ apps/plugin.h (working copy) @@ -121,6 +121,11 @@ #define PREFIX(_x_) _x_ #endif +#if defined(SIMULATOR) && defined(PLUGIN) +#undef VIRT_PTR +#define VIRT_PTR rb->vp_dummy +#endif + #define PLUGIN_MAGIC 0x526F634B /* RocK */ /* increase this every time the api struct changes */ @@ -756,6 +761,13 @@ void (*lcd_set_enable_hook)(void (*enable_hook)(void)); struct event_queue *button_queue; #endif + void (*lang_init_helper)(unsigned char *src, unsigned char **dest, int count); + int (*lang_load_helper)(const char *filename, const unsigned char *src, + unsigned char **dest, unsigned char *ptr, int max, int size); + unsigned char **language_strings; +#ifdef SIMULATOR + unsigned char *vp_dummy; +#endif }; /* plugin header */