mirror of
https://github.com/dborth/snes9xgx.git
synced 2024-12-24 18:21:50 +01:00
framework for multilanguage support
This commit is contained in:
parent
92cbfafede
commit
b533b8824f
12
Makefile.gc
12
Makefile.gc
@ -18,7 +18,7 @@ include $(DEVKITPPC)/gamecube_rules
|
||||
TARGET := snes9xgx-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/snes9x source/sz
|
||||
INCLUDES := source/snes9x source/ngc
|
||||
|
||||
@ -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,12 +139,16 @@ $(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 $<)
|
||||
$(bin2o)
|
||||
|
12
Makefile.wii
12
Makefile.wii
@ -18,7 +18,7 @@ include $(DEVKITPPC)/wii_rules
|
||||
TARGET := snes9xgx-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/snes9x source/sz source/unzip
|
||||
INCLUDES := source/snes9x source/ngc source/unzip
|
||||
|
||||
@ -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,12 +140,16 @@ $(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 $<)
|
||||
$(bin2o)
|
||||
|
@ -14,9 +14,32 @@
|
||||
|
||||
#include <gccore.h>
|
||||
|
||||
// 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;
|
||||
|
||||
@ -32,6 +55,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;
|
||||
|
||||
|
286
source/ngc/gettext.cpp
Normal file
286
source/ngc/gettext.cpp
Normal 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 "snes9xGX.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
12
source/ngc/gettext.h
Normal 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_ */
|
@ -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];
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -224,6 +224,10 @@ void GuiFileBrowser::Draw()
|
||||
this->UpdateEffects();
|
||||
}
|
||||
|
||||
void GuiFileBrowser::DrawTooltip()
|
||||
{
|
||||
}
|
||||
|
||||
void GuiFileBrowser::Update(GuiTrigger * t)
|
||||
{
|
||||
if(state == STATE_DISABLED || !t)
|
||||
|
@ -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)
|
||||
{
|
||||
for(int i=0; i<PAGESIZE; i++)
|
||||
@ -234,6 +240,22 @@ void GuiOptionBrowser::TriggerUpdate()
|
||||
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)
|
||||
{
|
||||
if(state == STATE_DISABLED || !t)
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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))
|
||||
|
@ -263,6 +263,9 @@ UpdateGUI (void *arg)
|
||||
UpdatePads();
|
||||
mainWindow->Draw();
|
||||
|
||||
if (mainWindow->GetState() != STATE_DISABLED)
|
||||
mainWindow->DrawTooltip();
|
||||
|
||||
#ifdef HW_RVL
|
||||
i = 3;
|
||||
do
|
||||
|
@ -346,7 +346,7 @@ void USBGeckoOutput()
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
//USBGeckoOutput(); // uncomment to enable USB gecko output
|
||||
USBGeckoOutput(); // uncomment to enable USB gecko output
|
||||
__exception_setreload(8);
|
||||
|
||||
#ifdef HW_DOL
|
||||
|
@ -61,6 +61,19 @@ enum
|
||||
const char ctrlName[6][24] =
|
||||
{ "SNES Controller", "SNES Mouse", "Superscope", "Justifier", "SNES Controllers (2)", "SNES 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;
|
||||
@ -89,6 +102,7 @@ struct SGCSettings{
|
||||
int MusicVolume;
|
||||
int SFXVolume;
|
||||
int Rumble;
|
||||
int language;
|
||||
};
|
||||
|
||||
void ExitApp();
|
||||
|
@ -84,11 +84,8 @@ LoadSRAMAuto (bool silent)
|
||||
return false;
|
||||
|
||||
if(LoadSRAM(filepath2, silent))
|
||||
{
|
||||
// rename this file - append Auto
|
||||
rename(filepath2, filepath); // rename file (to avoid duplicates)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -141,8 +138,21 @@ SaveSRAMAuto (bool silent)
|
||||
{
|
||||
char filepath[1024];
|
||||
|
||||
// look for file with no number or Auto appended
|
||||
if(!MakeFilePath(filepath, FILE_SRAM, Memory.ROMFilename, -1))
|
||||
return false;
|
||||
|
||||
FILE * fp = fopen (filepath, "rb");
|
||||
|
||||
if(fp) // file found
|
||||
{
|
||||
fclose (fp);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!MakeFilePath(filepath, FILE_SRAM, Memory.ROMFilename, 0))
|
||||
return false;
|
||||
}
|
||||
|
||||
return SaveSRAM(filepath, silent);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user