515 lines
14 KiB
C++
515 lines
14 KiB
C++
#include "../include/config.h"
|
|
#include "../include/OptionItem.h"
|
|
#include <JGE.h>
|
|
#include "../include/PlayerData.h"
|
|
#include "../include/Translate.h"
|
|
#include "../include/Subtypes.h"
|
|
#include "../include/TranslateKeys.h"
|
|
#include <dirent.h>
|
|
#include <stdlib.h>
|
|
#include <algorithm>
|
|
|
|
//OptionItem
|
|
OptionItem::OptionItem( int _id, string _displayValue): WGuiItem(_displayValue) {
|
|
id = _id;
|
|
mFocus=false;
|
|
}
|
|
|
|
//OptionInteger
|
|
void OptionInteger::Render(){
|
|
JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
|
|
mFont->DrawString(_(displayValue).c_str(), x + 2, y + 3);
|
|
char buf[512];
|
|
if (maxValue == 1){
|
|
if (value)
|
|
sprintf(buf, "%s", _("Yes").c_str());
|
|
else
|
|
sprintf(buf, "%s", _("No").c_str());
|
|
}else{
|
|
if(value == defValue && strDefault.size())
|
|
sprintf(buf, "%s", _(strDefault).c_str());
|
|
else
|
|
sprintf(buf, "%i", value);
|
|
}
|
|
mFont->DrawString(buf, width - 5, y + 3, JGETEXT_RIGHT);
|
|
}
|
|
|
|
OptionInteger::OptionInteger(int _id, string _displayValue, int _maxValue, int _increment, int _defV, string _sDef, int _minValue): OptionItem(_id, _displayValue){
|
|
defValue = _defV;
|
|
strDefault = _sDef;
|
|
maxValue = _maxValue;
|
|
minValue = _minValue;
|
|
increment = _increment;
|
|
value = ::options[id].number;
|
|
x = 0;
|
|
y = 0;
|
|
}
|
|
|
|
void OptionInteger::setData(){
|
|
if(id != INVALID_OPTION)
|
|
options[id] = GameOption(value);
|
|
}
|
|
|
|
//Option Select
|
|
void OptionSelect::initSelections(){
|
|
//Find currently active bit in the list.
|
|
for(size_t i=0;i<selections.size();i++){
|
|
if(selections[i] == options[id].str)
|
|
value = i;
|
|
}
|
|
}
|
|
|
|
void OptionSelect::Entering(JButton key){
|
|
OptionItem::Entering(key);
|
|
prior_value = value;
|
|
}
|
|
|
|
void OptionSelect::Render(){
|
|
JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
mFont->DrawString(_(displayValue).c_str(), x, y + 2);
|
|
|
|
if (value < selections.size())
|
|
mFont->DrawString(_(selections[value]).c_str(), x + width - 10, y + 2, JGETEXT_RIGHT);
|
|
else
|
|
mFont->DrawString(_("Unset").c_str(),x + width - 10, y + 2, JGETEXT_RIGHT);
|
|
}
|
|
|
|
void OptionSelect::setData(){
|
|
if(id == INVALID_OPTION) return;
|
|
|
|
if (value < selections.size())
|
|
options[id] = GameOption(selections[value]);
|
|
}
|
|
bool OptionSelect::Selectable(){
|
|
return (selections.size() > 1);
|
|
}
|
|
|
|
void OptionSelect::addSelection(string s){
|
|
selections.push_back(s);
|
|
}
|
|
|
|
//OptionProfile
|
|
const string OptionProfile::DIRTESTER = "collection.dat";
|
|
OptionProfile::OptionProfile(GameApp * _app, JGuiListener * jgl) : OptionDirectory(RESPATH"/profiles", Options::ACTIVE_PROFILE, "Profile", DIRTESTER){
|
|
app = _app;
|
|
listener = jgl;
|
|
height=60;
|
|
addSelection("Default");
|
|
sort(selections.begin(),selections.end());
|
|
mFocus = false;
|
|
initSelections();
|
|
populate();
|
|
};
|
|
|
|
void OptionProfile::addSelection(string s){
|
|
OptionDirectory::addSelection(s);
|
|
|
|
//Check how many options... if 1, we're not selectable.
|
|
if(selections.size() > 1)
|
|
canSelect = true;
|
|
else
|
|
canSelect = false;
|
|
|
|
}
|
|
void OptionProfile::updateValue(){
|
|
value++;
|
|
if (value > selections.size() - 1)
|
|
value=0;
|
|
|
|
populate();
|
|
}
|
|
|
|
void OptionProfile::Reload(){
|
|
OptionDirectory::Reload();
|
|
populate();
|
|
}
|
|
void OptionProfile::populate(){
|
|
string temp = options[Options::ACTIVE_PROFILE].str;
|
|
if (value >= selections.size()){ //TODO fail gracefully.
|
|
return;
|
|
}
|
|
options[Options::ACTIVE_PROFILE].str = selections[value];
|
|
PlayerData * pdata = NEW PlayerData(app->collection);
|
|
|
|
int unlocked = 0, sets = setlist.size();
|
|
std::ifstream file(options.profileFile(PLAYER_SETTINGS).c_str());
|
|
std::string s;
|
|
if(file){
|
|
while(std::getline(file,s)){
|
|
if(s.substr(0, 9) == "unlocked_")
|
|
unlocked++;
|
|
}
|
|
file.close();
|
|
}
|
|
|
|
options[Options::ACTIVE_PROFILE] = temp;
|
|
|
|
char buf[512], format[512];
|
|
sprintf(format,"%s\n%s\n%s\n",_("Credits: %i").c_str(),_("Cards: %i").c_str(),_("Sets: %i (of %i)").c_str());
|
|
sprintf(buf,format,pdata->credits,pdata->collection->totalCards(),unlocked,sets);
|
|
preview = buf;
|
|
|
|
SAFE_DELETE(pdata);
|
|
}
|
|
|
|
void OptionProfile::Render(){
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT);
|
|
mFont->SetScale(1);
|
|
int spacing = 2+(int)mFont->GetHeight();
|
|
|
|
int pX, pY;
|
|
pX = x;
|
|
pY = y;
|
|
char buf[512];
|
|
if(selections[value] == "Default")
|
|
sprintf(buf,"player/avatar.jpg");
|
|
else
|
|
sprintf(buf,"profiles/%s/avatar.jpg",selections[value].c_str());
|
|
string filename = buf;
|
|
JQuad * mAvatar = resources.RetrieveTempQuad(filename,TEXTURE_SUB_EXACT);
|
|
|
|
if(mAvatar){
|
|
renderer->RenderQuad(mAvatar,x,pY);
|
|
pX += 40;
|
|
}
|
|
|
|
mFont->SetColor(getColor(WGuiColor::TEXT_HEADER));
|
|
mFont->DrawString(selections[value].c_str(), pX, pY + 2, JGETEXT_LEFT);
|
|
mFont->SetScale(.8);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT_BODY));
|
|
mFont->DrawString(preview.c_str(), pX, pY + spacing + 2, JGETEXT_LEFT);
|
|
mFont->SetScale(1);
|
|
|
|
}
|
|
void OptionProfile::Entering(JButton key){
|
|
mFocus = true;
|
|
initialValue = value;
|
|
}
|
|
|
|
void OptionProfile::confirmChange(bool confirmed){
|
|
if (initialValue >= selections.size())
|
|
return;
|
|
|
|
int result;
|
|
|
|
if(confirmed) result = value;
|
|
else result = initialValue;
|
|
|
|
options[Options::ACTIVE_PROFILE] = selections[result];
|
|
value = result;
|
|
|
|
populate();
|
|
if(listener && confirmed){
|
|
listener->ButtonPressed(-102,5);
|
|
initialValue = value;
|
|
}
|
|
return;
|
|
}
|
|
//OptionLanguage
|
|
OptionLanguage::OptionLanguage(string _displayValue) : OptionSelect(Options::LANG,_displayValue)
|
|
{
|
|
Reload();
|
|
initSelections();
|
|
};
|
|
|
|
void OptionLanguage::setData(){
|
|
if(id == INVALID_OPTION) return;
|
|
|
|
if (value < selections.size()){
|
|
options[id] = GameOption(actual_data[value]);
|
|
Translator::EndInstance();
|
|
Translator::GetInstance()->init();
|
|
Translator::GetInstance()->tempValues.clear();
|
|
}
|
|
}
|
|
void OptionLanguage::confirmChange(bool confirmed){
|
|
if(!confirmed)
|
|
value = prior_value;
|
|
else{
|
|
setData();
|
|
if(Changed()){
|
|
options[id] = GameOption(actual_data[value]);
|
|
Translator::EndInstance();
|
|
Translator::GetInstance()->init();
|
|
Translator::GetInstance()->tempValues.clear();
|
|
}
|
|
prior_value = value;
|
|
}
|
|
}
|
|
void OptionLanguage::Reload(){
|
|
struct dirent *mDit;
|
|
DIR *mDip;
|
|
|
|
mDip = opendir("Res/lang");
|
|
|
|
while ((mDit = readdir(mDip))){
|
|
string filename = "Res/lang/";
|
|
filename += mDit->d_name;
|
|
std::ifstream file(filename.c_str());
|
|
string s;
|
|
string lang;
|
|
if(file){
|
|
if(std::getline(file,s)){
|
|
if (!s.size()){
|
|
lang = "";
|
|
}else{
|
|
if (s[s.size()-1] == '\r')
|
|
s.erase(s.size()-1); //Handle DOS files
|
|
size_t found = s.find("#LANG:");
|
|
if (found != 0) lang = "";
|
|
else lang = s.substr(6);
|
|
}
|
|
}
|
|
file.close();
|
|
}
|
|
|
|
if (lang.size()){
|
|
string filen = mDit->d_name;
|
|
addSelection(filen.substr(0,filen.size()-4),lang);
|
|
}
|
|
}
|
|
closedir(mDip);
|
|
initSelections();
|
|
}
|
|
void OptionLanguage::addSelection(string s,string show){
|
|
selections.push_back(show);
|
|
actual_data.push_back(s);
|
|
}
|
|
void OptionLanguage::initSelections(){
|
|
//Find currently active bit in the list.
|
|
for(size_t i=0;i<actual_data.size();i++){
|
|
if(actual_data[i] == options[id].str)
|
|
value = i;
|
|
}
|
|
}
|
|
bool OptionLanguage::Visible(){
|
|
if(selections.size() > 1)
|
|
return true;
|
|
return false;
|
|
}
|
|
bool OptionLanguage::Selectable(){
|
|
if(selections.size() > 1)
|
|
return true;
|
|
return false;
|
|
}
|
|
//OptionDirectory
|
|
void OptionDirectory::Reload(){
|
|
DIR *mDip;
|
|
struct dirent *mDit;
|
|
char buf[PATH_MAX];
|
|
mDip = opendir(root.c_str());
|
|
|
|
if (!mDip) return;
|
|
|
|
while ((mDit = readdir(mDip))){
|
|
sprintf(buf,"%s/%s/%s", root.c_str(), mDit->d_name, type.c_str());
|
|
std::ifstream file(buf);
|
|
if (!file) continue;
|
|
file.close();
|
|
if (find(selections.begin(), selections.end(), mDit->d_name) == selections.end())
|
|
addSelection(mDit->d_name);
|
|
}
|
|
|
|
closedir(mDip);
|
|
mDip = NULL;
|
|
initSelections();
|
|
}
|
|
|
|
OptionDirectory::OptionDirectory(string root, int id, string displayValue, string type): OptionSelect(id, displayValue), root(root), type(type){
|
|
DIR *mDip;
|
|
struct dirent *mDit;
|
|
char buf[PATH_MAX];
|
|
|
|
mDip = opendir(root.c_str());
|
|
if(!mDip) return;
|
|
|
|
while ((mDit = readdir(mDip))){
|
|
sprintf(buf,"%s/%s/%s", root.c_str(), mDit->d_name, type.c_str());
|
|
std::ifstream file(buf);
|
|
if (!file) continue;
|
|
file.close();
|
|
addSelection(mDit->d_name);
|
|
}
|
|
|
|
closedir(mDip);
|
|
mDip = NULL;
|
|
initSelections();
|
|
}
|
|
|
|
const string OptionTheme::DIRTESTER = "preview.png";
|
|
OptionTheme::OptionTheme() : OptionDirectory(RESPATH"/themes", Options::ACTIVE_THEME, "Current Theme", DIRTESTER){
|
|
addSelection("Default");
|
|
sort(selections.begin(),selections.end());
|
|
initSelections();
|
|
mFocus=false;
|
|
bChecked = false;
|
|
}
|
|
JQuad * OptionTheme::getImage(){
|
|
char buf[512];
|
|
string val = selections[value];
|
|
if(val == "Default")
|
|
sprintf(buf,"graphics/preview.png");
|
|
else
|
|
sprintf(buf,"themes/%s/preview.png",val.c_str());
|
|
string filename = buf;
|
|
return resources.RetrieveTempQuad(filename,TEXTURE_SUB_EXACT);
|
|
}
|
|
|
|
float OptionTheme::getHeight(){
|
|
return 130;
|
|
};
|
|
void OptionTheme::updateValue(){
|
|
OptionDirectory::updateValue();
|
|
bChecked = false;
|
|
}
|
|
|
|
void OptionTheme::Render(){
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
char buf[512];
|
|
if(!bChecked){
|
|
author = "";
|
|
bChecked = true;
|
|
if(selections[value] == "Default")
|
|
sprintf(buf,RESPATH"/graphics/themeinfo.txt");
|
|
else
|
|
sprintf(buf,RESPATH"/themes/%s/themeinfo.txt",selections[value].c_str());
|
|
std::ifstream file(buf);
|
|
if(file){
|
|
string temp;
|
|
std::getline(file,temp);
|
|
for(unsigned int x=0;x<17,x<temp.size();x++){
|
|
if(isprint(temp[x])) //Clear stuff that breaks mFont->DrawString, cuts to 16 chars.
|
|
author += temp[x];
|
|
}
|
|
file.close();
|
|
}
|
|
}
|
|
sprintf(buf,_("Theme: %s").c_str(),selections[value].c_str());
|
|
|
|
JQuad * q = getImage();
|
|
if(q){
|
|
float scale = 128 / q->mHeight;
|
|
renderer->RenderQuad(q,x, y,0,scale,scale);
|
|
}
|
|
|
|
JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT_HEADER));
|
|
mFont->DrawString(buf, x + 2, y + 2);
|
|
if(bChecked && author.size()){
|
|
mFont->SetColor(getColor(WGuiColor::TEXT_BODY));
|
|
mFont->SetScale(.8);
|
|
float hi = mFont->GetHeight();
|
|
sprintf(buf,_("Artist: %s").c_str(),author.c_str());
|
|
mFont->DrawString(buf, x + 2, y + getHeight() - hi);
|
|
mFont->SetScale(1);
|
|
}
|
|
}
|
|
|
|
bool OptionTheme::Visible(){
|
|
if(selections.size() <= 1)
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
void OptionTheme::confirmChange(bool confirmed){
|
|
bChecked = false;
|
|
if(!confirmed)
|
|
value = prior_value;
|
|
else{
|
|
setData();
|
|
resources.Refresh(); //Update images
|
|
prior_value = value;
|
|
}
|
|
}
|
|
|
|
OptionKey::OptionKey(GameStateOptions* g, LocalKeySym from, JButton to) : WGuiItem(""), from(from), to(to), grabbed(false), g(g), btnMenu(NULL) {}
|
|
|
|
void OptionKey::Update(float dt) { if (btnMenu) btnMenu->Update(dt); }
|
|
void OptionKey::Render() {
|
|
JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT);
|
|
mFont->SetColor(getColor(WGuiColor::TEXT));
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
|
|
if (LOCAL_KEY_NONE == from)
|
|
{
|
|
string msg = _("New binding...");
|
|
mFont->DrawString(msg, (SCREEN_WIDTH - mFont->GetStringWidth(msg.c_str())) / 2, y + 2);
|
|
}
|
|
else
|
|
{
|
|
const KeyRep& rep = translateKey(from);
|
|
if (rep.second)
|
|
renderer->RenderQuad(rep.second, x + 4, y + 3, 0, 16.0 / rep.second->mHeight, 16.0 / rep.second->mHeight);
|
|
else
|
|
mFont->DrawString(rep.first, x + 4, y + 3, JGETEXT_LEFT);
|
|
const KeyRep& rep2 = translateKey(to);
|
|
if (rep2.second)
|
|
{
|
|
float ratio = 16.0 / rep2.second->mHeight;
|
|
renderer->RenderQuad(rep2.second, x + width - (ratio * rep2.second->mWidth) - 2, y + 3, 0, ratio, ratio);
|
|
}
|
|
else
|
|
mFont->DrawString(rep2.first, width - 4, y + 3, JGETEXT_RIGHT);
|
|
}
|
|
}
|
|
bool OptionKey::CheckUserInput(JButton key) {
|
|
if (btnMenu)
|
|
return btnMenu->CheckUserInput(key);
|
|
if (JGE_BTN_OK == key) {
|
|
grabbed = true;
|
|
g->GrabKeyboard(this);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
static const JButton btnList[] = {JGE_BTN_MENU, JGE_BTN_CTRL, JGE_BTN_RIGHT,
|
|
JGE_BTN_LEFT, JGE_BTN_UP, JGE_BTN_DOWN,
|
|
JGE_BTN_OK, JGE_BTN_CANCEL, JGE_BTN_PRI,
|
|
JGE_BTN_SEC, JGE_BTN_PREV, JGE_BTN_NEXT,
|
|
#ifdef LINUX
|
|
JGE_BTN_FULLSCREEN,
|
|
#endif
|
|
JGE_BTN_NONE};
|
|
void OptionKey::KeyPressed(LocalKeySym key) {
|
|
from = key;
|
|
g->UngrabKeyboard(this);
|
|
grabbed = false;
|
|
|
|
btnMenu = NEW SimpleMenu(0, this, Constants::MENU_FONT, 80, 10);
|
|
for (int i = sizeof(btnList) / sizeof(btnList[0]) - 1; i >= 0; --i) {
|
|
const KeyRep& rep = translateKey(btnList[i]);
|
|
btnMenu->Add(i, rep.first.c_str());
|
|
}
|
|
}
|
|
bool OptionKey::isModal() { return grabbed || btnMenu; }
|
|
void OptionKey::Overlay()
|
|
{
|
|
JRenderer * renderer = JRenderer::GetInstance();
|
|
JLBFont * mFont = resources.GetJLBFont(Constants::OPTION_FONT);
|
|
mFont->SetColor(ARGB(255, 0, 0, 0));
|
|
if (grabbed) {
|
|
static const int x = 30, y = 45;
|
|
renderer->FillRoundRect(x, y, SCREEN_WIDTH - 2*x, 50, 2, ARGB(200, 200, 200, 255));
|
|
string msg = _("Press a key to associate.");
|
|
mFont->DrawString(msg, (SCREEN_WIDTH - mFont->GetStringWidth(msg.c_str())) / 2, y + 20);
|
|
}
|
|
else if (btnMenu)
|
|
btnMenu->Render();
|
|
}
|
|
void OptionKey::ButtonPressed(int controllerId, int controlId) {
|
|
to = btnList[controlId];
|
|
SAFE_DELETE(btnMenu);
|
|
btnMenu = NULL;
|
|
}
|
|
bool OptionKey::Visible() { return JGE_BTN_NONE != to || LOCAL_KEY_NONE == from || btnMenu != NULL; }
|
|
bool OptionKey::Selectable() { return JGE_BTN_NONE != to || LOCAL_KEY_NONE == from || btnMenu != NULL; }
|