From 5102f60d8154c4931fe26a423d7bfff211a87b48 Mon Sep 17 00:00:00 2001 From: dborth Date: Mon, 25 Jan 2010 08:23:03 +0000 Subject: [PATCH] framework for multilanguage support --- Makefile.gc | 12 +- Makefile.wii | 12 +- source/ngc/fceugx.h | 14 ++ source/ngc/filelist.h | 25 +++ source/ngc/gettext.cpp | 286 +++++++++++++++++++++++++++ source/ngc/gettext.h | 12 ++ source/ngc/gui/gui.h | 49 ++++- source/ngc/gui/gui_button.cpp | 24 +++ source/ngc/gui/gui_element.cpp | 11 +- source/ngc/gui/gui_filebrowser.cpp | 4 + source/ngc/gui/gui_optionbrowser.cpp | 22 +++ source/ngc/gui/gui_savebrowser.cpp | 10 +- source/ngc/gui/gui_text.cpp | 17 +- source/ngc/gui/gui_window.cpp | 21 ++ source/ngc/lang/de.lang | 2 + source/ngc/lang/en.lang | 2 + source/ngc/lang/es.lang | 2 + source/ngc/lang/fr.lang | 2 + source/ngc/lang/it.lang | 2 + source/ngc/lang/jp.lang | 2 + source/ngc/lang/ko.lang | 2 + source/ngc/lang/nl.lang | 2 + source/ngc/lang/zh.lang | 2 + source/ngc/menu.cpp | 3 + 24 files changed, 522 insertions(+), 18 deletions(-) create mode 100644 source/ngc/gettext.cpp create mode 100644 source/ngc/gettext.h create mode 100644 source/ngc/lang/de.lang create mode 100644 source/ngc/lang/en.lang create mode 100644 source/ngc/lang/es.lang create mode 100644 source/ngc/lang/fr.lang create mode 100644 source/ngc/lang/it.lang create mode 100644 source/ngc/lang/jp.lang create mode 100644 source/ngc/lang/ko.lang create mode 100644 source/ngc/lang/nl.lang create mode 100644 source/ngc/lang/zh.lang diff --git a/Makefile.gc b/Makefile.gc index 4f54161..89b3277 100644 --- a/Makefile.gc +++ b/Makefile.gc @@ -18,7 +18,7 @@ include $(DEVKITPPC)/gamecube_rules TARGET := fceugx-gc TARGETDIR := executables BUILD := build_gc -SOURCES := source/ngc/images source/ngc/sounds source/ngc/fonts \ +SOURCES := source/ngc/images source/ngc/sounds source/ngc/fonts source/ngc/lang \ source/ngc/gui source/ngc \ source/fceultra source/fceultra/boards source/fceultra/input \ source/fceultra/utils source/fceultra/mappers source/fceultra/mbshare \ @@ -71,6 +71,7 @@ CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf))) +LANGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.lang))) PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm))) @@ -85,7 +86,8 @@ endif export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ $(sFILES:.s=.o) $(SFILES:.S=.o) \ - $(TTFFILES:.ttf=.ttf.o) $(PNGFILES:.png=.png.o) \ + $(TTFFILES:.ttf=.ttf.o) $(LANGFILES:.lang=.lang.o) \ + $(PNGFILES:.png=.png.o) \ $(PCMFILES:.pcm=.pcm.o) #--------------------------------------------------------------------------------- @@ -137,11 +139,15 @@ $(OUTPUT).dol: $(OUTPUT).elf $(OUTPUT).elf: $(OFILES) #--------------------------------------------------------------------------------- -# This rule links in binary data with .ttf, .png, and .mp3 extensions +# This rule links in binary data with these extensions: ttf lang png pcm #--------------------------------------------------------------------------------- %.ttf.o : %.ttf @echo $(notdir $<) $(bin2o) + +%.lang.o : %.lang + @echo $(notdir $<) + $(bin2o) %.png.o : %.png @echo $(notdir $<) diff --git a/Makefile.wii b/Makefile.wii index dae9efb..1ce9984 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -18,7 +18,7 @@ include $(DEVKITPPC)/wii_rules TARGET := fceugx-wii TARGETDIR := executables BUILD := build_wii -SOURCES := source/ngc/images source/ngc/sounds source/ngc/fonts \ +SOURCES := source/ngc/images source/ngc/sounds source/ngc/fonts source/ngc/lang \ source/ngc/gui source/ngc \ source/fceultra source/fceultra/boards source/fceultra/input \ source/fceultra/utils source/fceultra/mappers source/fceultra/mbshare \ @@ -71,6 +71,7 @@ CPPFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.cpp))) sFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.s))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf))) +LANGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.lang))) PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg))) PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm))) @@ -86,7 +87,8 @@ endif export OFILES := $(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ $(sFILES:.s=.o) $(SFILES:.S=.o) \ - $(TTFFILES:.ttf=.ttf.o) $(PNGFILES:.png=.png.o) \ + $(TTFFILES:.ttf=.ttf.o) $(LANGFILES:.lang=.lang.o) \ + $(PNGFILES:.png=.png.o) \ $(OGGFILES:.ogg=.ogg.o) $(PCMFILES:.pcm=.pcm.o) #--------------------------------------------------------------------------------- @@ -138,11 +140,15 @@ $(OUTPUT).dol: $(OUTPUT).elf $(OUTPUT).elf: $(OFILES) #--------------------------------------------------------------------------------- -# This rule links in binary data with .ttf, .png, and .mp3 extensions +# This rule links in binary data with these extensions: ttf lang png ogg pcm #--------------------------------------------------------------------------------- %.ttf.o : %.ttf @echo $(notdir $<) $(bin2o) + +%.lang.o : %.lang + @echo $(notdir $<) + $(bin2o) %.png.o : %.png @echo $(notdir $<) diff --git a/source/ngc/fceugx.h b/source/ngc/fceugx.h index 1c8a82e..2f88e97 100644 --- a/source/ngc/fceugx.h +++ b/source/ngc/fceugx.h @@ -56,6 +56,19 @@ enum const char ctrlName[6][20] = { "NES Controller", "NES Zapper", "NES Controllers (2)", "NES Controllers (4)" }; +enum { + LANG_JAPANESE = 0, + LANG_ENGLISH, + LANG_GERMAN, + LANG_FRENCH, + LANG_SPANISH, + LANG_ITALIAN, + LANG_DUTCH, + LANG_SIMP_CHINESE, + LANG_TRAD_CHINESE, + LANG_KOREAN +}; + struct SGCSettings{ int AutoLoad; int AutoSave; @@ -90,6 +103,7 @@ struct SGCSettings{ int MusicVolume; int SFXVolume; int Rumble; + int language; }; void ExitApp(); diff --git a/source/ngc/filelist.h b/source/ngc/filelist.h index 20965df..4fc0362 100644 --- a/source/ngc/filelist.h +++ b/source/ngc/filelist.h @@ -15,9 +15,32 @@ #include +// Fonts extern const u8 font_ttf[]; extern const u32 font_ttf_size; +// Languages +extern const u8 jp_lang[]; +extern const u32 jp_lang_size; +extern const u8 en_lang[]; +extern const u32 en_lang_size; +extern const u8 de_lang[]; +extern const u32 de_lang_size; +extern const u8 fr_lang[]; +extern const u32 fr_lang_size; +extern const u8 es_lang[]; +extern const u32 es_lang_size; +extern const u8 it_lang[]; +extern const u32 it_lang_size; +extern const u8 nl_lang[]; +extern const u32 nl_lang_size; +extern const u8 zh_lang[]; +extern const u32 zh_lang_size; +extern const u8 ko_lang[]; +extern const u32 ko_lang_size; + +// Sounds + extern const u8 bg_music_ogg[]; extern const u32 bg_music_ogg_size; @@ -33,6 +56,8 @@ extern const u32 button_over_pcm_size; extern const u8 button_click_pcm[]; extern const u32 button_click_pcm_size; +// Graphics + extern const u8 logo_png[]; extern const u32 logo_png_size; diff --git a/source/ngc/gettext.cpp b/source/ngc/gettext.cpp new file mode 100644 index 0000000..fd022d0 --- /dev/null +++ b/source/ngc/gettext.cpp @@ -0,0 +1,286 @@ +#include +#include +#include +#include +#include + +#include "gettext.h" +#include "filelist.h" +#include "fceugx.h" + +typedef struct _MSG +{ + u32 id; + char* msgstr; + struct _MSG *next; +} MSG; +static MSG *baseMSG = 0; + +#define HASHWORDBITS 32 + +/* Defines the so called `hashpjw' function by P.J. Weinberger + [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, + 1986, 1987 Bell Telephone Laboratories, Inc.] */ +static inline u32 hash_string(const char *str_param) +{ + u32 hval, g; + const char *str = str_param; + + /* Compute the hash value for the given string. */ + hval = 0; + while (*str != '\0') + { + hval <<= 4; + hval += (u8) * str++; + g = hval & ((u32) 0xf << (HASHWORDBITS - 4)); + if (g != 0) + { + hval ^= g >> (HASHWORDBITS - 8); + hval ^= g; + } + } + return hval; +} + +/* Expand some escape sequences found in the argument string. */ +static char * +expand_escape(const char *str) +{ + char *retval, *rp; + const char *cp = str; + + retval = (char *) malloc(strlen(str) + 1); + if (retval == NULL) + return NULL; + rp = retval; + + while (cp[0] != '\0' && cp[0] != '\\') + *rp++ = *cp++; + if (cp[0] == '\0') + goto terminate; + do + { + + /* Here cp[0] == '\\'. */ + switch (*++cp) + { + case '\"': /* " */ + *rp++ = '\"'; + ++cp; + break; + case 'a': /* alert */ + *rp++ = '\a'; + ++cp; + break; + case 'b': /* backspace */ + *rp++ = '\b'; + ++cp; + break; + case 'f': /* form feed */ + *rp++ = '\f'; + ++cp; + break; + case 'n': /* new line */ + *rp++ = '\n'; + ++cp; + break; + case 'r': /* carriage return */ + *rp++ = '\r'; + ++cp; + break; + case 't': /* horizontal tab */ + *rp++ = '\t'; + ++cp; + break; + case 'v': /* vertical tab */ + *rp++ = '\v'; + ++cp; + break; + case '\\': + *rp = '\\'; + ++cp; + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + { + int ch = *cp++ - '0'; + + if (*cp >= '0' && *cp <= '7') + { + ch *= 8; + ch += *cp++ - '0'; + + if (*cp >= '0' && *cp <= '7') + { + ch *= 8; + ch += *cp++ - '0'; + } + } + *rp = ch; + } + break; + default: + *rp = '\\'; + break; + } + + while (cp[0] != '\0' && cp[0] != '\\') + *rp++ = *cp++; + } while (cp[0] != '\0'); + + /* Terminate string. */ + terminate: *rp = '\0'; + return retval; +} + +static MSG *findMSG(u32 id) +{ + MSG *msg; + for (msg = baseMSG; msg; msg = msg->next) + { + if (msg->id == id) + return msg; + } + return NULL; +} + +static MSG *setMSG(const char *msgid, const char *msgstr) +{ + u32 id = hash_string(msgid); + MSG *msg = findMSG(id); + if (!msg) + { + msg = (MSG *) malloc(sizeof(MSG)); + msg->id = id; + msg->msgstr = NULL; + msg->next = baseMSG; + baseMSG = msg; + } + if (msg) + { + if (msgstr) + { + if (msg->msgstr) + free(msg->msgstr); + //msg->msgstr = strdup(msgstr); + msg->msgstr = expand_escape(msgstr); + } + return msg; + } + return NULL; +} + +static void gettextCleanUp(void) +{ + while (baseMSG) + { + MSG *nextMsg = baseMSG->next; + free(baseMSG->msgstr); + free(baseMSG); + baseMSG = nextMsg; + } +} + +static char * memfgets(char * dst, int maxlen, char * src) +{ + if(!src || !dst || maxlen <= 0) + return NULL; + + char * newline = strchr(src, '\n'); + + if(newline == NULL) + return NULL; + + memcpy(dst, src, (newline-src)); + dst[(newline-src)] = 0; + return ++newline; +} + +bool LoadLanguage() +{ + char line[200]; + char *lastID = NULL; + + char *file, *eof; + + switch(GCSettings.language) + { + case LANG_JAPANESE: file = (char *)jp_lang; eof = file + jp_lang_size; break; + case LANG_ENGLISH: file = (char *)en_lang; eof = file + en_lang_size; break; + case LANG_GERMAN: file = (char *)de_lang; eof = file + de_lang_size; break; + case LANG_FRENCH: file = (char *)fr_lang; eof = file + fr_lang_size; break; + case LANG_SPANISH: file = (char *)es_lang; eof = file + es_lang_size; break; + case LANG_ITALIAN: file = (char *)it_lang; eof = file + it_lang_size; break; + case LANG_DUTCH: file = (char *)nl_lang; eof = file + nl_lang_size; break; + case LANG_SIMP_CHINESE: + case LANG_TRAD_CHINESE: file = (char *)zh_lang; eof = file + zh_lang_size; break; + case LANG_KOREAN: file = (char *)ko_lang; eof = file + ko_lang_size; break; + default: return false; + } + + gettextCleanUp(); + + while (file && file < eof) + { + file = memfgets(line, sizeof(line), file); + + if(!file) + break; + + // lines starting with # are comments + if (line[0] == '#') + continue; + + if (strncmp(line, "msgid \"", 7) == 0) + { + char *msgid, *end; + if (lastID) + { + free(lastID); + lastID = NULL; + } + msgid = &line[7]; + end = strrchr(msgid, '"'); + if (end && end - msgid > 1) + { + *end = 0; + lastID = strdup(msgid); + } + } + else if (strncmp(line, "msgstr \"", 8) == 0) + { + char *msgstr, *end; + + if (lastID == NULL) + continue; + + msgstr = &line[8]; + end = strrchr(msgstr, '"'); + if (end && end - msgstr > 1) + { + *end = 0; + setMSG(lastID, msgstr); + } + free(lastID); + lastID = NULL; + } + } + return true; +} + +const char *gettext(const char *msgid) +{ + MSG *msg = findMSG(hash_string(msgid)); + + if (msg && msg->msgstr) + { + return msg->msgstr; + } + return msgid; +} diff --git a/source/ngc/gettext.h b/source/ngc/gettext.h new file mode 100644 index 0000000..1309e93 --- /dev/null +++ b/source/ngc/gettext.h @@ -0,0 +1,12 @@ +#ifndef _GETTEXT_H_ +#define _GETTEXT_H_ + +bool LoadLanguage(); + +/* + * input msg = a text in ASCII + * output = the translated msg in utf-8 + */ +const char *gettext(const char *msg); + +#endif /* _GETTEXT_H_ */ diff --git a/source/ngc/gui/gui.h b/source/ngc/gui/gui.h index 3c46aa1..fa05456 100644 --- a/source/ngc/gui/gui.h +++ b/source/ngc/gui/gui.h @@ -393,11 +393,15 @@ class GuiElement //!\param hor Horizontal alignment (ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTRE) //!\param vert Vertical alignment (ALIGN_TOP, ALIGN_BOTTOM, ALIGN_MIDDLE) virtual void SetAlignment(int hor, int vert); + //!Called when the language has changed, to obtain new text values for all text elements + virtual void ResetText(); //!Called constantly to allow the element to respond to the current input data //!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD virtual void Update(GuiTrigger * t); //!Called constantly to redraw the element virtual void Draw(); + //!Called constantly to redraw the element's tooltip + virtual void DrawTooltip(); protected: GuiTrigger * trigger[2]; //!< GuiTriggers (input actions) that this element responds to UpdateCallback updateCB; //!< Callback function to call when this element is updated @@ -495,8 +499,12 @@ class GuiWindow : public GuiElement //!Moves the selected element to the element above or below //!\param d Direction to move (-1 = up, 1 = down) void MoveSelectionVert(int d); + //!Resets the text for all contained elements + void ResetText(); //!Draws all the elements in this GuiWindow void Draw(); + //!Draws all of the tooltips in this GuiWindow + void DrawTooltip(); //!Updates the window and all elements contains within //!Allows the GuiWindow and all elements to respond to the input data specified //!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD @@ -647,6 +655,8 @@ class GuiText : public GuiElement //!\param hor Horizontal alignment (ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTRE) //!\param vert Vertical alignment (ALIGN_TOP, ALIGN_BOTTOM, ALIGN_MIDDLE) void SetAlignment(int hor, int vert); + //!Updates the text to the selected language + void ResetText(); //!Constantly called to draw the text void Draw(); protected: @@ -664,6 +674,32 @@ class GuiText : public GuiElement bool wrap; //!< Wrapping toggle }; +//!Display, manage, and manipulate tooltips in the GUI +class GuiTooltip : public GuiElement +{ + public: + //!Constructor + //!\param t Text + GuiTooltip(const char *t); + //!Destructor + ~GuiTooltip(); + //!Gets the element's current scale + float GetScale(); + //!Sets the text of the GuiTooltip element + //!\param t Text + void SetText(const char * t); + //!Constantly called to draw the GuiTooltip + void DrawTooltip(); + + time_t time1, time2; //!< Tooltip times + + protected: + GuiImage leftImage; //!< Tooltip left image + GuiImage tileImage; //!< Tooltip tile image + GuiImage rightImage; //!< Tooltip right image + GuiText *text; //!< Tooltip text +}; + //!Display, manage, and manipulate buttons in the GUI. Buttons can have images, icons, text, and sound set (all of which are optional) class GuiButton : public GuiElement { @@ -671,7 +707,7 @@ class GuiButton : public GuiElement //!Constructor //!\param w Width //!\param h Height - GuiButton(int w, int h); + GuiButton(int w = 0, int h = 0); //!Destructor ~GuiButton(); //!Sets the button's image @@ -723,8 +759,15 @@ class GuiButton : public GuiElement //!Sets the sound to play on click //!\param s Pointer to GuiSound object void SetSoundClick(GuiSound * s); + //!Sets the tooltip for the button + //!\param t Tooltip + void SetTooltip(GuiTooltip * t); //!Constantly called to draw the GuiButton void Draw(); + //!Constantly called to draw the GuiButton's tooltip + void DrawTooltip(); + //!Resets the text for all contained elements + void ResetText(); //!Constantly called to allow the GuiButton to respond to updated input data //!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD void Update(GuiTrigger * t); @@ -744,6 +787,7 @@ class GuiButton : public GuiElement GuiSound * soundOver; //!< Sound to play for STATE_SELECTED GuiSound * soundHold; //!< Sound to play for STATE_HELD GuiSound * soundClick; //!< Sound to play for STATE_CLICKED + GuiTooltip * tooltip; //!< Tooltip to display on over }; typedef struct _keytype { @@ -808,6 +852,7 @@ class GuiOptionBrowser : public GuiElement public: GuiOptionBrowser(int w, int h, OptionList * l); ~GuiOptionBrowser(); + void SetCol1Position(int x); void SetCol2Position(int x); int FindMenuItem(int c, int d); int GetClickedOption(); @@ -815,6 +860,7 @@ class GuiOptionBrowser : public GuiElement void SetFocus(int f); void Draw(); void TriggerUpdate(); + void ResetText(); void Update(GuiTrigger * t); GuiText * optionVal[PAGESIZE]; protected: @@ -921,6 +967,7 @@ class GuiFileBrowser : public GuiElement void ResetState(); void SetFocus(int f); void Draw(); + void DrawTooltip(); void TriggerUpdate(); void Update(GuiTrigger * t); GuiButton * fileList[FILE_PAGESIZE]; diff --git a/source/ngc/gui/gui_button.cpp b/source/ngc/gui/gui_button.cpp index f5cddee..3b4dd5e 100644 --- a/source/ngc/gui/gui_button.cpp +++ b/source/ngc/gui/gui_button.cpp @@ -37,6 +37,7 @@ GuiButton::GuiButton(int w, int h) soundOver = NULL; soundHold = NULL; soundClick = NULL; + tooltip = NULL; selectable = true; holdable = false; clickable = true; @@ -121,6 +122,12 @@ void GuiButton::SetSoundClick(GuiSound * snd) { soundClick = snd; } +void GuiButton::SetTooltip(GuiTooltip* t) +{ + tooltip = t; + if(t) + tooltip->SetParent(this); +} /** * Draw the button on screen @@ -177,6 +184,23 @@ void GuiButton::Draw() this->UpdateEffects(); } +void GuiButton::DrawTooltip() +{ + if(tooltip) + tooltip->DrawTooltip(); +} + +void GuiButton::ResetText() +{ + for(int i=0; i<3; i++) + { + if(label[i]) + label[i]->ResetText(); + if(labelOver[i]) + labelOver[i]->ResetText(); + } +} + void GuiButton::Update(GuiTrigger * t) { if(state == STATE_CLICKED || state == STATE_DISABLED || !t) diff --git a/source/ngc/gui/gui_element.cpp b/source/ngc/gui/gui_element.cpp index c44f3bf..09f3725 100644 --- a/source/ngc/gui/gui_element.cpp +++ b/source/ngc/gui/gui_element.cpp @@ -511,13 +511,18 @@ int GuiElement::GetSelected() return -1; } -/** - * Draw an element on screen. - */ +void GuiElement::ResetText() +{ +} + void GuiElement::Draw() { } +void GuiElement::DrawTooltip() +{ +} + bool GuiElement::IsInside(int x, int y) { if(unsigned(x - this->GetLeft()) < unsigned(width) diff --git a/source/ngc/gui/gui_filebrowser.cpp b/source/ngc/gui/gui_filebrowser.cpp index ca9b70a..4caf25f 100644 --- a/source/ngc/gui/gui_filebrowser.cpp +++ b/source/ngc/gui/gui_filebrowser.cpp @@ -224,6 +224,10 @@ void GuiFileBrowser::Draw() this->UpdateEffects(); } +void GuiFileBrowser::DrawTooltip() +{ +} + void GuiFileBrowser::Update(GuiTrigger * t) { if(state == STATE_DISABLED || !t) diff --git a/source/ngc/gui/gui_optionbrowser.cpp b/source/ngc/gui/gui_optionbrowser.cpp index 2d5cd90..616a529 100644 --- a/source/ngc/gui/gui_optionbrowser.cpp +++ b/source/ngc/gui/gui_optionbrowser.cpp @@ -134,6 +134,12 @@ GuiOptionBrowser::~GuiOptionBrowser() } } +void GuiOptionBrowser::SetCol1Position(int x) +{ + for(int i=0; iSetPosition(x,0); +} + void GuiOptionBrowser::SetCol2Position(int x) { for(int i=0; i= 0) + { + optionBtn[i]->ResetText(); + next = this->FindMenuItem(next, 1); + } + else + break; + } +} + void GuiOptionBrowser::Update(GuiTrigger * t) { if(state == STATE_DISABLED || !t) diff --git a/source/ngc/gui/gui_savebrowser.cpp b/source/ngc/gui/gui_savebrowser.cpp index e26d529..af7a540 100644 --- a/source/ngc/gui/gui_savebrowser.cpp +++ b/source/ngc/gui/gui_savebrowser.cpp @@ -321,8 +321,8 @@ void GuiSaveBrowser::Update(GuiTrigger * t) { saveDate[0]->SetText(NULL); saveDate[1]->SetText(NULL); - saveTime[0]->SetText("New SRAM"); - saveTime[1]->SetText("New Snapshot"); + saveTime[0]->SetText("New RAM"); + saveTime[1]->SetText("New State"); saveType[0]->SetText(NULL); saveType[1]->SetText(NULL); savePreviewImg[0]->SetImage(gameSaveBlank); @@ -348,10 +348,10 @@ void GuiSaveBrowser::Update(GuiTrigger * t) saveDate[i]->SetText(saves->date[listOffset+i]); saveTime[i]->SetText(saves->time[listOffset+i]); - if(saves->type[listOffset+i] == FILE_SRAM) - sprintf(savetext, "SRAM"); + if(saves->type[listOffset+i] == FILE_RAM) + sprintf(savetext, "RAM"); else - sprintf(savetext, "Snapshot"); + sprintf(savetext, "State"); len = strlen(saves->filename[listOffset+i]); if(len > 10 && diff --git a/source/ngc/gui/gui_text.cpp b/source/ngc/gui/gui_text.cpp index c42eb88..11d431b 100644 --- a/source/ngc/gui/gui_text.cpp +++ b/source/ngc/gui/gui_text.cpp @@ -9,6 +9,7 @@ ***************************************************************************/ #include "gui.h" +#include "../gettext.h" static GXColor presetColor = (GXColor){255, 255, 255, 255}; static int currentSize = 0; @@ -46,7 +47,7 @@ GuiText::GuiText(const char * t, int s, GXColor c) if(t) { origText = strdup(t); - text = charToWideChar(t); + text = charToWideChar(gettext(t)); } } @@ -75,7 +76,7 @@ GuiText::GuiText(const char * t) if(t) { origText = strdup(t); - text = charToWideChar(t); + text = charToWideChar(gettext(t)); } } @@ -110,7 +111,7 @@ void GuiText::SetText(const char * t) if(t) { origText = strdup(t); - text = charToWideChar(t); + text = charToWideChar(gettext(t)); } } @@ -200,6 +201,16 @@ void GuiText::SetAlignment(int hor, int vert) alignmentVert = vert; } +void GuiText::ResetText() +{ + if(!origText) + return; + if(text) + delete[] text; + + text = charToWideChar(gettext(origText)); +} + /** * Draw the text on screen */ diff --git a/source/ngc/gui/gui_window.cpp b/source/ngc/gui/gui_window.cpp index 5933e3a..92981c2 100644 --- a/source/ngc/gui/gui_window.cpp +++ b/source/ngc/gui/gui_window.cpp @@ -99,6 +99,18 @@ void GuiWindow::Draw() Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0xbe, 0xca, 0xd5, 0x70},1); } +void GuiWindow::DrawTooltip() +{ + if(_elements.size() == 0 || !this->IsVisible()) + return; + + for (u8 i = 0; i < _elements.size(); i++) + { + try { _elements.at(i)->DrawTooltip(); } + catch (const std::exception& e) { } + } +} + void GuiWindow::ResetState() { if(state != STATE_DISABLED) @@ -384,6 +396,15 @@ void GuiWindow::MoveSelectionVert(int dir) } } +void GuiWindow::ResetText() +{ + for (u8 i = 0; i < _elements.size(); i++) + { + try { _elements.at(i)->ResetText(); } + catch (const std::exception& e) { } + } +} + void GuiWindow::Update(GuiTrigger * t) { if(_elements.size() == 0 || (state == STATE_DISABLED && parentElement)) diff --git a/source/ngc/lang/de.lang b/source/ngc/lang/de.lang new file mode 100644 index 0000000..85d8364 --- /dev/null +++ b/source/ngc/lang/de.lang @@ -0,0 +1,2 @@ +msgid " " +msgstr "" diff --git a/source/ngc/lang/en.lang b/source/ngc/lang/en.lang new file mode 100644 index 0000000..85d8364 --- /dev/null +++ b/source/ngc/lang/en.lang @@ -0,0 +1,2 @@ +msgid " " +msgstr "" diff --git a/source/ngc/lang/es.lang b/source/ngc/lang/es.lang new file mode 100644 index 0000000..85d8364 --- /dev/null +++ b/source/ngc/lang/es.lang @@ -0,0 +1,2 @@ +msgid " " +msgstr "" diff --git a/source/ngc/lang/fr.lang b/source/ngc/lang/fr.lang new file mode 100644 index 0000000..85d8364 --- /dev/null +++ b/source/ngc/lang/fr.lang @@ -0,0 +1,2 @@ +msgid " " +msgstr "" diff --git a/source/ngc/lang/it.lang b/source/ngc/lang/it.lang new file mode 100644 index 0000000..85d8364 --- /dev/null +++ b/source/ngc/lang/it.lang @@ -0,0 +1,2 @@ +msgid " " +msgstr "" diff --git a/source/ngc/lang/jp.lang b/source/ngc/lang/jp.lang new file mode 100644 index 0000000..85d8364 --- /dev/null +++ b/source/ngc/lang/jp.lang @@ -0,0 +1,2 @@ +msgid " " +msgstr "" diff --git a/source/ngc/lang/ko.lang b/source/ngc/lang/ko.lang new file mode 100644 index 0000000..85d8364 --- /dev/null +++ b/source/ngc/lang/ko.lang @@ -0,0 +1,2 @@ +msgid " " +msgstr "" diff --git a/source/ngc/lang/nl.lang b/source/ngc/lang/nl.lang new file mode 100644 index 0000000..85d8364 --- /dev/null +++ b/source/ngc/lang/nl.lang @@ -0,0 +1,2 @@ +msgid " " +msgstr "" diff --git a/source/ngc/lang/zh.lang b/source/ngc/lang/zh.lang new file mode 100644 index 0000000..85d8364 --- /dev/null +++ b/source/ngc/lang/zh.lang @@ -0,0 +1,2 @@ +msgid " " +msgstr "" diff --git a/source/ngc/menu.cpp b/source/ngc/menu.cpp index 57d79d7..e061a15 100644 --- a/source/ngc/menu.cpp +++ b/source/ngc/menu.cpp @@ -269,6 +269,9 @@ UpdateGUI (void *arg) UpdatePads(); mainWindow->Draw(); + if (mainWindow->GetState() != STATE_DISABLED) + mainWindow->DrawTooltip(); + #ifdef HW_RVL i = 3; do