framework for multilanguage support

This commit is contained in:
dborth 2010-01-25 08:25:28 +00:00
parent fee8667d9e
commit bbd50f86a3
23 changed files with 517 additions and 13 deletions

View File

@ -18,7 +18,7 @@ include $(DEVKITPPC)/gamecube_rules
TARGET := vbagx_gc TARGET := vbagx_gc
TARGETDIR := executables TARGETDIR := executables
BUILD := build_gc 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/sz source/unzip \ source/ngc/gui source/ngc source/sz source/unzip \
source/vba source/vba/apu source/vba/common \ source/vba source/vba/apu source/vba/common \
source/vba/gb source/vba/gba source/vba/gb source/vba/gba
@ -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)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf))) TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf)))
LANGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.lang)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm))) PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm)))
@ -85,7 +86,8 @@ endif
export OFILES := $(addsuffix .o,$(BINFILES)) \ export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ $(CPPFILES:.cpp=.o) $(CFILES:.c=.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) $(PCMFILES:.pcm=.pcm.o)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@ -137,11 +139,15 @@ $(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES) $(OUTPUT).elf: $(OFILES)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# This rule links in binary data with .ttf and .png extensions # This rule links in binary data with these extensions: ttf lang png pcm
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
%.ttf.o : %.ttf %.ttf.o : %.ttf
@echo $(notdir $<) @echo $(notdir $<)
$(bin2o) $(bin2o)
%.lang.o : %.lang
@echo $(notdir $<)
$(bin2o)
%.png.o : %.png %.png.o : %.png
@echo $(notdir $<) @echo $(notdir $<)

View File

@ -18,7 +18,7 @@ include $(DEVKITPPC)/wii_rules
TARGET := vbagx_wii TARGET := vbagx_wii
TARGETDIR := executables TARGETDIR := executables
BUILD := build_wii 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/sz source/unzip \ source/ngc/gui source/ngc source/sz source/unzip \
source/vba source/vba/apu source/vba/common \ source/vba source/vba/apu source/vba/common \
source/vba/gb source/vba/gba source/vba/gb source/vba/gba
@ -72,6 +72,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)))
SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S))) SFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.S)))
TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf))) TTFFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ttf)))
LANGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.lang)))
PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png))) PNGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.png)))
OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg))) OGGFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.ogg)))
PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm))) PCMFILES := $(foreach dir,$(SOURCES),$(notdir $(wildcard $(dir)/*.pcm)))
@ -87,7 +88,8 @@ endif
export OFILES := $(addsuffix .o,$(BINFILES)) \ export OFILES := $(addsuffix .o,$(BINFILES)) \
$(CPPFILES:.cpp=.o) $(CFILES:.c=.o) \ $(CPPFILES:.cpp=.o) $(CFILES:.c=.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) $(OGGFILES:.ogg=.ogg.o) $(PCMFILES:.pcm=.pcm.o)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
@ -139,11 +141,15 @@ $(OUTPUT).dol: $(OUTPUT).elf
$(OUTPUT).elf: $(OFILES) $(OUTPUT).elf: $(OFILES)
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
# This rule links in binary data with .ttf and .png extensions # This rule links in binary data with these extensions: ttf lang png ogg pcm
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
%.ttf.o : %.ttf %.ttf.o : %.ttf
@echo $(notdir $<) @echo $(notdir $<)
$(bin2o) $(bin2o)
%.lang.o : %.lang
@echo $(notdir $<)
$(bin2o)
%.png.o : %.png %.png.o : %.png
@echo $(notdir $<) @echo $(notdir $<)

View File

@ -14,9 +14,32 @@
#include <gccore.h> #include <gccore.h>
// Fonts
extern const u8 font_ttf[]; extern const u8 font_ttf[];
extern const u32 font_ttf_size; 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 u8 bg_music_ogg[];
extern const u32 bg_music_ogg_size; extern const u32 bg_music_ogg_size;
@ -32,6 +55,8 @@ extern const u32 button_over_pcm_size;
extern const u8 button_click_pcm[]; extern const u8 button_click_pcm[];
extern const u32 button_click_pcm_size; extern const u32 button_click_pcm_size;
// Graphics
extern const u8 logo_png[]; extern const u8 logo_png[];
extern const u32 logo_png_size; extern const u32 logo_png_size;

286
source/ngc/gettext.cpp Normal file
View File

@ -0,0 +1,286 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <gctypes.h>
#include <unistd.h>
#include "gettext.h"
#include "filelist.h"
#include "vba.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;
}

12
source/ngc/gettext.h Normal file
View File

@ -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_ */

View File

@ -393,11 +393,15 @@ class GuiElement
//!\param hor Horizontal alignment (ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTRE) //!\param hor Horizontal alignment (ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTRE)
//!\param vert Vertical alignment (ALIGN_TOP, ALIGN_BOTTOM, ALIGN_MIDDLE) //!\param vert Vertical alignment (ALIGN_TOP, ALIGN_BOTTOM, ALIGN_MIDDLE)
virtual void SetAlignment(int hor, int vert); 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 //!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 //!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD
virtual void Update(GuiTrigger * t); virtual void Update(GuiTrigger * t);
//!Called constantly to redraw the element //!Called constantly to redraw the element
virtual void Draw(); virtual void Draw();
//!Called constantly to redraw the element's tooltip
virtual void DrawTooltip();
protected: protected:
GuiTrigger * trigger[2]; //!< GuiTriggers (input actions) that this element responds to GuiTrigger * trigger[2]; //!< GuiTriggers (input actions) that this element responds to
UpdateCallback updateCB; //!< Callback function to call when this element is updated 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 //!Moves the selected element to the element above or below
//!\param d Direction to move (-1 = up, 1 = down) //!\param d Direction to move (-1 = up, 1 = down)
void MoveSelectionVert(int d); void MoveSelectionVert(int d);
//!Resets the text for all contained elements
void ResetText();
//!Draws all the elements in this GuiWindow //!Draws all the elements in this GuiWindow
void Draw(); void Draw();
//!Draws all of the tooltips in this GuiWindow
void DrawTooltip();
//!Updates the window and all elements contains within //!Updates the window and all elements contains within
//!Allows the GuiWindow and all elements to respond to the input data specified //!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 //!\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 hor Horizontal alignment (ALIGN_LEFT, ALIGN_RIGHT, ALIGN_CENTRE)
//!\param vert Vertical alignment (ALIGN_TOP, ALIGN_BOTTOM, ALIGN_MIDDLE) //!\param vert Vertical alignment (ALIGN_TOP, ALIGN_BOTTOM, ALIGN_MIDDLE)
void SetAlignment(int hor, int vert); void SetAlignment(int hor, int vert);
//!Updates the text to the selected language
void ResetText();
//!Constantly called to draw the text //!Constantly called to draw the text
void Draw(); void Draw();
protected: protected:
@ -664,6 +674,32 @@ class GuiText : public GuiElement
bool wrap; //!< Wrapping toggle 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) //!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 class GuiButton : public GuiElement
{ {
@ -671,7 +707,7 @@ class GuiButton : public GuiElement
//!Constructor //!Constructor
//!\param w Width //!\param w Width
//!\param h Height //!\param h Height
GuiButton(int w, int h); GuiButton(int w = 0, int h = 0);
//!Destructor //!Destructor
~GuiButton(); ~GuiButton();
//!Sets the button's image //!Sets the button's image
@ -723,8 +759,15 @@ class GuiButton : public GuiElement
//!Sets the sound to play on click //!Sets the sound to play on click
//!\param s Pointer to GuiSound object //!\param s Pointer to GuiSound object
void SetSoundClick(GuiSound * s); void SetSoundClick(GuiSound * s);
//!Sets the tooltip for the button
//!\param t Tooltip
void SetTooltip(GuiTooltip * t);
//!Constantly called to draw the GuiButton //!Constantly called to draw the GuiButton
void Draw(); 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 //!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 //!\param t Pointer to a GuiTrigger, containing the current input data from PAD/WPAD
void Update(GuiTrigger * t); void Update(GuiTrigger * t);
@ -744,6 +787,7 @@ class GuiButton : public GuiElement
GuiSound * soundOver; //!< Sound to play for STATE_SELECTED GuiSound * soundOver; //!< Sound to play for STATE_SELECTED
GuiSound * soundHold; //!< Sound to play for STATE_HELD GuiSound * soundHold; //!< Sound to play for STATE_HELD
GuiSound * soundClick; //!< Sound to play for STATE_CLICKED GuiSound * soundClick; //!< Sound to play for STATE_CLICKED
GuiTooltip * tooltip; //!< Tooltip to display on over
}; };
typedef struct _keytype { typedef struct _keytype {
@ -808,6 +852,7 @@ class GuiOptionBrowser : public GuiElement
public: public:
GuiOptionBrowser(int w, int h, OptionList * l); GuiOptionBrowser(int w, int h, OptionList * l);
~GuiOptionBrowser(); ~GuiOptionBrowser();
void SetCol1Position(int x);
void SetCol2Position(int x); void SetCol2Position(int x);
int FindMenuItem(int c, int d); int FindMenuItem(int c, int d);
int GetClickedOption(); int GetClickedOption();
@ -815,6 +860,7 @@ class GuiOptionBrowser : public GuiElement
void SetFocus(int f); void SetFocus(int f);
void Draw(); void Draw();
void TriggerUpdate(); void TriggerUpdate();
void ResetText();
void Update(GuiTrigger * t); void Update(GuiTrigger * t);
GuiText * optionVal[PAGESIZE]; GuiText * optionVal[PAGESIZE];
protected: protected:
@ -921,6 +967,7 @@ class GuiFileBrowser : public GuiElement
void ResetState(); void ResetState();
void SetFocus(int f); void SetFocus(int f);
void Draw(); void Draw();
void DrawTooltip();
void TriggerUpdate(); void TriggerUpdate();
void Update(GuiTrigger * t); void Update(GuiTrigger * t);
GuiButton * fileList[FILE_PAGESIZE]; GuiButton * fileList[FILE_PAGESIZE];

View File

@ -37,6 +37,7 @@ GuiButton::GuiButton(int w, int h)
soundOver = NULL; soundOver = NULL;
soundHold = NULL; soundHold = NULL;
soundClick = NULL; soundClick = NULL;
tooltip = NULL;
selectable = true; selectable = true;
holdable = false; holdable = false;
clickable = true; clickable = true;
@ -121,6 +122,12 @@ void GuiButton::SetSoundClick(GuiSound * snd)
{ {
soundClick = snd; soundClick = snd;
} }
void GuiButton::SetTooltip(GuiTooltip* t)
{
tooltip = t;
if(t)
tooltip->SetParent(this);
}
/** /**
* Draw the button on screen * Draw the button on screen
@ -177,6 +184,23 @@ void GuiButton::Draw()
this->UpdateEffects(); 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) void GuiButton::Update(GuiTrigger * t)
{ {
if(state == STATE_CLICKED || state == STATE_DISABLED || !t) if(state == STATE_CLICKED || state == STATE_DISABLED || !t)

View File

@ -511,13 +511,18 @@ int GuiElement::GetSelected()
return -1; return -1;
} }
/** void GuiElement::ResetText()
* Draw an element on screen. {
*/ }
void GuiElement::Draw() void GuiElement::Draw()
{ {
} }
void GuiElement::DrawTooltip()
{
}
bool GuiElement::IsInside(int x, int y) bool GuiElement::IsInside(int x, int y)
{ {
if(unsigned(x - this->GetLeft()) < unsigned(width) if(unsigned(x - this->GetLeft()) < unsigned(width)

View File

@ -224,6 +224,10 @@ void GuiFileBrowser::Draw()
this->UpdateEffects(); this->UpdateEffects();
} }
void GuiFileBrowser::DrawTooltip()
{
}
void GuiFileBrowser::Update(GuiTrigger * t) void GuiFileBrowser::Update(GuiTrigger * t)
{ {
if(state == STATE_DISABLED || !t) if(state == STATE_DISABLED || !t)

View File

@ -134,6 +134,12 @@ GuiOptionBrowser::~GuiOptionBrowser()
} }
} }
void GuiOptionBrowser::SetCol1Position(int x)
{
for(int i=0; i<PAGESIZE; i++)
optionTxt[i]->SetPosition(x,0);
}
void GuiOptionBrowser::SetCol2Position(int x) void GuiOptionBrowser::SetCol2Position(int x)
{ {
for(int i=0; i<PAGESIZE; i++) for(int i=0; i<PAGESIZE; i++)
@ -234,6 +240,22 @@ void GuiOptionBrowser::TriggerUpdate()
listChanged = true; listChanged = true;
} }
void GuiOptionBrowser::ResetText()
{
int next = listOffset;
for(int i=0; i<PAGESIZE; i++)
{
if(next >= 0)
{
optionBtn[i]->ResetText();
next = this->FindMenuItem(next, 1);
}
else
break;
}
}
void GuiOptionBrowser::Update(GuiTrigger * t) void GuiOptionBrowser::Update(GuiTrigger * t)
{ {
if(state == STATE_DISABLED || !t) if(state == STATE_DISABLED || !t)

View File

@ -9,6 +9,7 @@
***************************************************************************/ ***************************************************************************/
#include "gui.h" #include "gui.h"
#include "../gettext.h"
static GXColor presetColor = (GXColor){255, 255, 255, 255}; static GXColor presetColor = (GXColor){255, 255, 255, 255};
static int currentSize = 0; static int currentSize = 0;
@ -46,7 +47,7 @@ GuiText::GuiText(const char * t, int s, GXColor c)
if(t) if(t)
{ {
origText = strdup(t); origText = strdup(t);
text = charToWideChar(t); text = charToWideChar(gettext(t));
} }
} }
@ -75,7 +76,7 @@ GuiText::GuiText(const char * t)
if(t) if(t)
{ {
origText = strdup(t); origText = strdup(t);
text = charToWideChar(t); text = charToWideChar(gettext(t));
} }
} }
@ -110,7 +111,7 @@ void GuiText::SetText(const char * t)
if(t) if(t)
{ {
origText = strdup(t); origText = strdup(t);
text = charToWideChar(t); text = charToWideChar(gettext(t));
} }
} }
@ -200,6 +201,16 @@ void GuiText::SetAlignment(int hor, int vert)
alignmentVert = vert; alignmentVert = vert;
} }
void GuiText::ResetText()
{
if(!origText)
return;
if(text)
delete[] text;
text = charToWideChar(gettext(origText));
}
/** /**
* Draw the text on screen * Draw the text on screen
*/ */

View File

@ -99,6 +99,18 @@ void GuiWindow::Draw()
Menu_DrawRectangle(0,0,screenwidth,screenheight,(GXColor){0xbe, 0xca, 0xd5, 0x70},1); 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() void GuiWindow::ResetState()
{ {
if(state != STATE_DISABLED) 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) void GuiWindow::Update(GuiTrigger * t)
{ {
if(_elements.size() == 0 || (state == STATE_DISABLED && parentElement)) if(_elements.size() == 0 || (state == STATE_DISABLED && parentElement))

2
source/ngc/lang/de.lang Normal file
View File

@ -0,0 +1,2 @@
msgid " "
msgstr ""

2
source/ngc/lang/en.lang Normal file
View File

@ -0,0 +1,2 @@
msgid " "
msgstr ""

2
source/ngc/lang/es.lang Normal file
View File

@ -0,0 +1,2 @@
msgid " "
msgstr ""

2
source/ngc/lang/fr.lang Normal file
View File

@ -0,0 +1,2 @@
msgid " "
msgstr ""

2
source/ngc/lang/it.lang Normal file
View File

@ -0,0 +1,2 @@
msgid " "
msgstr ""

2
source/ngc/lang/jp.lang Normal file
View File

@ -0,0 +1,2 @@
msgid " "
msgstr ""

2
source/ngc/lang/ko.lang Normal file
View File

@ -0,0 +1,2 @@
msgid " "
msgstr ""

2
source/ngc/lang/nl.lang Normal file
View File

@ -0,0 +1,2 @@
msgid " "
msgstr ""

2
source/ngc/lang/zh.lang Normal file
View File

@ -0,0 +1,2 @@
msgid " "
msgstr ""

View File

@ -255,6 +255,9 @@ UpdateGUI (void *arg)
UpdatePads(); UpdatePads();
mainWindow->Draw(); mainWindow->Draw();
if (mainWindow->GetState() != STATE_DISABLED)
mainWindow->DrawTooltip();
#ifdef HW_RVL #ifdef HW_RVL
i = 3; i = 3;
do do

View File

@ -43,6 +43,19 @@ enum {
FILE_ROM FILE_ROM
}; };
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{ struct SGCSettings{
float gbaZoomHor; // GBA horizontal zoom amount float gbaZoomHor; // GBA horizontal zoom amount
float gbaZoomVert; // GBA vertical zoom amount float gbaZoomVert; // GBA vertical zoom amount
@ -64,6 +77,7 @@ struct SGCSettings{
int MusicVolume; int MusicVolume;
int SFXVolume; int SFXVolume;
int Rumble; int Rumble;
int language;
char LoadFolder[MAXPATHLEN]; // Path to game files char LoadFolder[MAXPATHLEN]; // Path to game files
char SaveFolder[MAXPATHLEN]; // Path to save files char SaveFolder[MAXPATHLEN]; // Path to save files
char CheatFolder[MAXPATHLEN]; // Path to cheat files char CheatFolder[MAXPATHLEN]; // Path to cheat files