Jeck - Resolved issue 44 and issue 45.

* Options can now use specialized loading functions. OptionEnum should work now.
 * Options are now stored in memory as a map<integer,GameOption>.
This commit is contained in:
wagic.jeck
2009-09-23 00:24:43 +00:00
parent 433897bf38
commit e577f3e378
10 changed files with 650 additions and 244 deletions
+139 -52
View File
@@ -14,25 +14,95 @@ using std::string;
#define PLAYER_SETTINGS "options.txt" #define PLAYER_SETTINGS "options.txt"
#define PLAYER_COLLECTION "collection.dat" #define PLAYER_COLLECTION "collection.dat"
struct Options { #define INVALID_OPTION -1
static const string MUSICVOLUME;
static const string SFXVOLUME; //Note to self-- provide some form of options initialization.
static const string DIFFICULTY_MODE_UNLOCKED;
static const string MOMIR_MODE_UNLOCKED; class Options {
static const string EVILTWIN_MODE_UNLOCKED; public:
static const string RANDOMDECK_MODE_UNLOCKED; friend class GameSettings;
static const string DIFFICULTY; enum {
static const string CACHESIZE; //Values /must/ match ordering in optionNames, or everything loads wrong.
static const string PLASMAEFFECT; //Profile settings
static const string INTERRUPT_SECONDS; ACTIVE_THEME,
static const string INTERRUPTMYSPELLS; ACTIVE_MODE,
static const string INTERRUPTMYABILITIES; MUSICVOLUME,
static const string OSD; SFXVOLUME,
static const string ACTIVE_PROFILE; DIFFICULTY,
static const string ACTIVE_THEME; PLASMAEFFECT,
static const string ACTIVE_MODE; OSD,
static const string CLOSEDHAND; CLOSEDHAND,
static const string HANDDIRECTION; HANDDIRECTION,
INTERRUPT_SECONDS,
//My interrupts
INTERRUPTMYSPELLS,
INTERRUPTMYABILITIES,
//Other interrupts
INTERRUPT_BEFOREBEGIN,
INTERRUPT_UNTAP,
INTERRUPT_UPKEEP,
INTERRUPT_DRAW,
INTERRUPT_FIRSTMAIN,
INTERRUPT_BEGINCOMBAT,
INTERRUPT_ATTACKERS,
INTERRUPT_BLOCKERS,
INTERRUPT_DAMAGE,
INTERRUPT_ENDCOMBAT,
INTERRUPT_SECONDMAIN,
INTERRUPT_ENDTURN,
INTERRUPT_CLEANUP,
INTERRUPT_AFTEREND,
//Global settings
ACTIVE_PROFILE,
DIFFICULTY_MODE_UNLOCKED,
MOMIR_MODE_UNLOCKED,
EVILTWIN_MODE_UNLOCKED,
RANDOMDECK_MODE_UNLOCKED,
CACHESIZE,
//Theme metrics. These will be phased out fairly soon.
THEME_METRICS, //Start of theme metrics.
LOADING_TC = THEME_METRICS,
STATS_TC,
SCROLLER_TC,
SCROLLER_FC,
MAINMENU_TC,
POPUP_MENU_FC,
POPUP_MENU_TC,
POPUP_MENU_TCH,
MSG_FAIL_TC,
OPTION_ITEM_FC,
OPTION_ITEM_TC,
OPTION_ITEM_TCH,
OPTION_HEADER_FC,
OPTION_HEADER_TC,
OPTION_SCROLLBAR_FC,
OPTION_SCROLLBAR_FCH,
OPTION_TAB_FC,
OPTION_TAB_FCH,
OPTION_TAB_TC,
OPTION_TAB_TCH,
OPTION_TEXT_TC,
OPTION_TEXT_FC,
KEY_TC,
KEY_TCH,
KEY_FC,
KEY_FCH,
KEYPAD_FC,
KEYPAD_FCH,
KEYPAD_TC,
LAST_NAMED, //Any option after this does not look up in optionNames.
SET_UNLOCKS = LAST_NAMED + 1, //For sets.
};
static int optionSet(int setID);
static int optionInterrupt(int gamePhase);
static int getID(string name);
static string getName(int option);
private:
static const char* optionNames[];
}; };
struct Metrics { struct Metrics {
@@ -40,35 +110,37 @@ struct Metrics {
//*_FC is fill-color, *_FCH is highlighted fill color //*_FC is fill-color, *_FCH is highlighted fill color
//*_B and *_BH are for secondary text/fill colors, if needed //*_B and *_BH are for secondary text/fill colors, if needed
//*_X, *_Y, *_W, *_H are x, y, width and height. //*_X, *_Y, *_W, *_H are x, y, width and height.
static const string LOADING_TC; enum {
static const string STATS_TC; LOADING_TC = Options::THEME_METRICS,
static const string SCROLLER_TC; STATS_TC,
static const string SCROLLER_FC; SCROLLER_TC,
static const string MAINMENU_TC; SCROLLER_FC,
static const string POPUP_MENU_FC; MAINMENU_TC,
static const string POPUP_MENU_TC; POPUP_MENU_FC,
static const string POPUP_MENU_TCH; POPUP_MENU_TC,
static const string MSG_FAIL_TC; POPUP_MENU_TCH,
static const string OPTION_ITEM_FC; MSG_FAIL_TC,
static const string OPTION_ITEM_TC; OPTION_ITEM_FC,
static const string OPTION_ITEM_TCH; OPTION_ITEM_TC,
static const string OPTION_HEADER_FC; OPTION_ITEM_TCH,
static const string OPTION_HEADER_TC; OPTION_HEADER_FC,
static const string OPTION_SCROLLBAR_FC; OPTION_HEADER_TC,
static const string OPTION_SCROLLBAR_FCH; OPTION_SCROLLBAR_FC,
static const string OPTION_TAB_FC; OPTION_SCROLLBAR_FCH,
static const string OPTION_TAB_FCH; OPTION_TAB_FC,
static const string OPTION_TAB_TC; OPTION_TAB_FCH,
static const string OPTION_TAB_TCH; OPTION_TAB_TC,
static const string OPTION_TEXT_TC; OPTION_TAB_TCH,
static const string OPTION_TEXT_FC; OPTION_TEXT_TC,
static const string KEY_TC; OPTION_TEXT_FC,
static const string KEY_TCH; KEY_TC,
static const string KEY_FC; KEY_TCH,
static const string KEY_FCH; KEY_FC,
static const string KEYPAD_FC; KEY_FCH,
static const string KEYPAD_FCH; KEYPAD_FC,
static const string KEYPAD_TC; KEYPAD_FCH,
KEYPAD_TC,
};
}; };
class GameOption { class GameOption {
@@ -83,6 +155,12 @@ public:
GameOption(int, string); GameOption(int, string);
}; };
struct EnumDefinition {
int findIndex(int value);
typedef pair<int, string> assoc;
vector<assoc> values;
};
class GameOptions { class GameOptions {
public: public:
@@ -90,13 +168,20 @@ class GameOptions {
int save(); int save();
int load(); int load();
static const char * phaseInterrupts[]; GameOption& operator[](int);
GameOption& operator[](string);
GameOptions(string filename); GameOptions(string filename);
~GameOptions(); ~GameOptions();
private: private:
map<string,GameOption> values; bool load_option(int id, string input); //Sends an option to the proper reader.
bool read_default(int id, string input);
bool read_enum(int id, string input, EnumDefinition * def);
bool save_option(std::ofstream * file, int id, string name, GameOption * opt); //Sends an option to the proper writer.
bool write_default(std::ofstream * file, string name, GameOption * opt);
bool write_enum(std::ofstream * file, string name, GameOption * opt, EnumDefinition * def);
map<int,GameOption> values;
}; };
class GameSettings{ class GameSettings{
@@ -124,11 +209,13 @@ public:
void checkProfile(); //Confirms that a profile is loaded and contains a collection. void checkProfile(); //Confirms that a profile is loaded and contains a collection.
void createUsersFirstDeck(int setId); void createUsersFirstDeck(int setId);
GameOption& operator[](string); GameOption& operator[](int);
GameOptions* profileOptions; GameOptions* profileOptions;
GameOptions* globalOptions; GameOptions* globalOptions;
GameOptions* themeOptions; GameOptions* themeOptions;
static GameOption invalid_option;
private: private:
GameApp * theGame; GameApp * theGame;
SimplePad * keypad; SimplePad * keypad;
+35 -17
View File
@@ -5,6 +5,7 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include "../include/GameApp.h" #include "../include/GameApp.h"
#include "../include/GameOptions.h"
using std::string; using std::string;
@@ -21,7 +22,8 @@ using std::string;
class OptionItem { class OptionItem {
public: public:
string displayValue, id; string displayValue;
int id;
int hasFocus; int hasFocus;
bool canSelect; bool canSelect;
bool bHidden; bool bHidden;
@@ -29,7 +31,7 @@ public:
float width, height; float width, height;
virtual ostream& toString(ostream& out)const; virtual ostream& toString(ostream& out)const;
OptionItem( string _id, string _displayValue); OptionItem( int _id, string _displayValue);
virtual ~OptionItem() {}; virtual ~OptionItem() {};
virtual bool Selectable() {return (canSelect && !bHidden);}; virtual bool Selectable() {return (canSelect && !bHidden);};
@@ -52,9 +54,9 @@ class OptionInteger:public OptionItem{
string strDefault; //What to call the default value. string strDefault; //What to call the default value.
int maxValue, increment; int maxValue, increment;
OptionInteger(string _id, string _displayValue, int _maxValue = 1, int _increment = 1, int _defV = 0, string _sDef = ""); OptionInteger(int _id, string _displayValue, int _maxValue = 1, int _increment = 1, int _defV = 0, string _sDef = "");
virtual void Reload() {if(id != "") value = options[id].number;}; virtual void Reload() {if(id != INVALID_OPTION) value = options[id].number;};
virtual void Render(); virtual void Render();
virtual void setData(); virtual void setData();
virtual void updateValue(){value+=increment; if (value>maxValue) value=0;}; virtual void updateValue(){value+=increment; if (value>maxValue) value=0;};
@@ -64,19 +66,19 @@ class OptionInteger:public OptionItem{
class OptionString:public OptionItem{ class OptionString:public OptionItem{
public: public:
string value; string value;
OptionString(string _id, string _displayValue); OptionString(int _id, string _displayValue);
virtual void Render(); virtual void Render();
virtual void setData(); virtual void setData();
virtual void updateValue(); virtual void updateValue();
virtual void Reload() {if(id != "") value = options[id].str;}; virtual void Reload() {if(id != INVALID_OPTION) value = options[id].str;};
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
bool bShowValue; bool bShowValue;
}; };
class OptionNewProfile:public OptionString{ class OptionNewProfile:public OptionString{
public: public:
OptionNewProfile(string _id, string _displayValue) : OptionString(_id, _displayValue) {bShowValue=false;}; OptionNewProfile(string _displayValue) : OptionString(INVALID_OPTION, _displayValue) {bShowValue=false;};
virtual void updateValue(); virtual void updateValue();
virtual void Update(float dt); virtual void Update(float dt);
virtual int Submode(); virtual int Submode();
@@ -85,7 +87,7 @@ class OptionNewProfile:public OptionString{
class OptionHeader:public OptionItem{ class OptionHeader:public OptionItem{
public: public:
OptionHeader(string _displayValue): OptionItem("", _displayValue) { canSelect=false;}; OptionHeader(string _displayValue): OptionItem(INVALID_OPTION, _displayValue) { canSelect=false;};
virtual void Render(); virtual void Render();
virtual void setData() {}; virtual void setData() {};
virtual void updateValue() {}; virtual void updateValue() {};
@@ -93,7 +95,7 @@ class OptionHeader:public OptionItem{
class OptionText:public OptionItem{ class OptionText:public OptionItem{
public: public:
OptionText(string _displayValue): OptionItem("", _displayValue) { canSelect=false;}; OptionText(string _displayValue): OptionItem(INVALID_OPTION, _displayValue) { canSelect=false;};
virtual void Render(); virtual void Render();
virtual void setData() {}; virtual void setData() {};
virtual void updateValue() {}; virtual void updateValue() {};
@@ -105,7 +107,7 @@ class OptionSelect:public OptionItem{
vector<string> selections; vector<string> selections;
virtual void addSelection(string s); virtual void addSelection(string s);
OptionSelect(string _id, string _displayValue): OptionItem(_id, _displayValue) {value = 0;}; OptionSelect(int _id, string _displayValue): OptionItem(_id, _displayValue) {value = 0;};
virtual void Reload(){initSelections();}; virtual void Reload(){initSelections();};
virtual void Render(); virtual void Render();
virtual void setData(); virtual void setData();
@@ -118,7 +120,7 @@ class OptionSelect:public OptionItem{
class OptionDirectory:public OptionSelect{ class OptionDirectory:public OptionSelect{
public: public:
virtual void Reload(); virtual void Reload();
OptionDirectory(string _root, string _id, string _displayValue); OptionDirectory(string _root, int _id, string _displayValue);
private: private:
string root; string root;
}; };
@@ -130,7 +132,7 @@ class OptionTheme:public OptionDirectory{
class OptionVolume: public OptionInteger{ class OptionVolume: public OptionInteger{
public: public:
OptionVolume(string _id, string _displayName, bool _bMusic = false); OptionVolume(int _id, string _displayName, bool _bMusic = false);
virtual void updateValue(); virtual void updateValue();
private: private:
bool bMusic; bool bMusic;
@@ -208,27 +210,43 @@ class OptionsMenu
class OptionEnum : public OptionItem { class OptionEnum : public OptionItem {
protected: protected:
typedef pair<int, string> assoc;
unsigned index; unsigned index;
vector<assoc> values;
public: public:
OptionEnum(string id, string displayValue) : OptionItem(id, displayValue), index(0) {}; OptionEnum(int id, string displayValue);
virtual void Reload(); virtual void Reload();
virtual void Render(); virtual void Render();
virtual void setData(); virtual void setData();
virtual void updateValue(); virtual void updateValue();
//ourDefined is a virtual wrapper for getDefinition()
virtual EnumDefinition * ourDefined() const {return getDefinition();};
static EnumDefinition * getDefinition();
virtual ostream& toString(ostream& out) const; virtual ostream& toString(ostream& out) const;
}; };
class OptionClosedHand : public OptionEnum { class OptionClosedHand : public OptionEnum {
public: public:
friend class GameSettings;
enum { INVISIBLE = 0, VISIBLE = 1 }; enum { INVISIBLE = 0, VISIBLE = 1 };
OptionClosedHand(string id, string displayValue); OptionClosedHand(int id, string displayValue);
static EnumDefinition * getDefinition();
EnumDefinition * ourDefined() const { return getDefinition();};
private:
static EnumDefinition * definition;
}; };
class OptionHandDirection : public OptionEnum { class OptionHandDirection : public OptionEnum {
public: public:
friend class GameSettings;
enum { VERTICAL = 0, HORIZONTAL = 1}; enum { VERTICAL = 0, HORIZONTAL = 1};
OptionHandDirection(string id, string displayValue); OptionHandDirection(int id, string displayValue);
static EnumDefinition * getDefinition();
EnumDefinition * ourDefined() const { return getDefinition();};
private:
static EnumDefinition * definition;
}; };
#endif #endif
+6 -9
View File
@@ -103,10 +103,7 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app){
}else if((unlocked = unlockRandomSet())) { }else if((unlocked = unlockRandomSet())) {
unlockedTex = resources.RetrieveTexture("set_unlocked.png", RETRIEVE_VRAM); unlockedTex = resources.RetrieveTexture("set_unlocked.png", RETRIEVE_VRAM);
unlockedQuad = resources.RetrieveQuad("set_unlocked.png", 2, 2, 396, 96); unlockedQuad = resources.RetrieveQuad("set_unlocked.png", 2, 2, 396, 96);
char buffer[4096]; options[Options::optionSet(unlocked - 1)] = GameOption(1);
unlockedString = MtgSets::SetsList->values[unlocked -1];
sprintf(buffer,"unlocked_%s", unlockedString.c_str());
options[buffer] = GameOption(1);
options.save(); options.save();
} }
if (unlocked){ if (unlocked){
@@ -239,9 +236,9 @@ int Credits::isRandomDeckUnlocked(){
int Credits::unlockRandomSet(){ int Credits::unlockRandomSet(){
if (rand() % 2) return 0; if (rand() % 2) return 0;
int setId = rand() % MtgSets::SetsList->nb_items; int setId = rand() % MtgSets::SetsList->nb_items;
char buffer[4096];
string s = MtgSets::SetsList->values[setId]; if (1 == options[Options::optionSet(setId)].number)
sprintf(buffer,"unlocked_%s", s.c_str()); return 0;
if (1 == options[buffer].number) return 0;
return setId + 1; return setId + 1; //We add 1 here to show success/failure. Be sure to subtract later.
} }
+1 -1
View File
@@ -168,7 +168,7 @@ void GameObserver::userRequestNextGamePhase(){
if ((cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) || if ((cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) ||
cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE || cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE ||
opponent()->isAI() || opponent()->isAI() ||
options[GameOptions::phaseInterrupts[currentGamePhase]].number) options[Options::optionInterrupt(currentGamePhase)].number)
mLayers->stackLayer()->AddNextGamePhase(); mLayers->stackLayer()->AddNextGamePhase();
else else
nextGamePhase(); nextGamePhase();
+333 -61
View File
@@ -2,49 +2,188 @@
#include "../include/utils.h" #include "../include/utils.h"
#include "../include/MTGDeck.h" #include "../include/MTGDeck.h"
#include "../include/GameOptions.h" #include "../include/GameOptions.h"
#include "../include/OptionItem.h"
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <stdlib.h> #include <stdlib.h>
#include <JGE.h> #include <JGE.h>
const char* GameOptions::phaseInterrupts[] = { const char * Options::optionNames[] = {
"interrupt ---", //Options set on a per-profile basis
"Theme",
"Mode",
"musicVolume",
"sfxVolume",
"difficulty",
"plasmaEffect",
"displayOSD",
"closed_hand",
"hand_direction",
"interruptSeconds",
"interruptMySpells",
"interruptMyAbilities",
//General interrupts
"interruptBeforeBegin",
"interruptUntap", "interruptUntap",
"interruptUpkeep", "interruptUpkeep",
"interruptDraw", "interruptDraw",
"interrupt Main phase 1", "interruptFirstMain",
"interrupt Combat begins", "interruptBeginCombat",
"interruptAttackers", "interruptAttackers",
"interruptBlockers", "interruptBlockers",
"interrupt Combat damage", "interruptDamage",
"interrupt Combat ends", "interruptEndCombat",
"interrupt Main phase 2", "interruptSecondMain",
"interrupt End of turn", "interruptEndTurn",
"interruptCleanup", "interruptCleanup",
"interrupt ---" "interruptAfterEnd",
};
//Profile options
const string Options::MUSICVOLUME = "musicVolume";
const string Options::SFXVOLUME = "sfxVolume";
const string Options::DIFFICULTY = "difficulty";
const string Options::PLASMAEFFECT = "plasmaEffect";
const string Options::INTERRUPT_SECONDS = "interruptSeconds";
const string Options::INTERRUPTMYSPELLS = "interruptMySpells";
const string Options::INTERRUPTMYABILITIES = "interruptMyAbilities";
const string Options::OSD = "displayOSD";
const string Options::ACTIVE_THEME = "Theme";
const string Options::ACTIVE_MODE = "Mode";
//Global options //Global options
const string Options::ACTIVE_PROFILE = "_gProfile"; "_gProfile",
const string Options::DIFFICULTY_MODE_UNLOCKED = "_gprx_handler"; //huhu "_gprx_handler",
const string Options::MOMIR_MODE_UNLOCKED = "_gprx_rimom"; //haha "_gprx_rimom",
const string Options::EVILTWIN_MODE_UNLOCKED = "_gprx_eviltwin"; "_gprx_eviltwin",
const string Options::RANDOMDECK_MODE_UNLOCKED = "_gprx_rnddeck"; "_gprx_rnddeck",
const string Options::CACHESIZE = "_gcacheSize"; "_gcacheSize",
const string Options::CLOSEDHAND = "closed_hand";
const string Options::HANDDIRECTION = "hand_direction";
//Theme metrics //Theme metrics
"_tLoadingTC",
"_tStatsTC",
"_tScrollerTC",
"_tScrollerFC",
"_tMainMenuTC",
"_tPopupMenuFC",
"_tPopupMenuTC",
"_tPopupMenuTCH",
"_tMsgFailTC",
"_tOptionItemFC",
"_tOptionItemTC",
"_tOptionItemTCH",
"_tOptionHeaderFC",
"_tOptionHeaderTC",
"_tOptionScrollbarFC",
"_tOptionScrollbarFCH",
"_tOptionHeaderFC",
"_tOptionHeaderFCH",
"_tOptionTabTC",
"_tOptionHeaderTCH",
"_tOptionTextTC",
"_tOptionTextFC",
"_tKeyTC",
"_tKeyTCH",
"_tKeyFC",
"_tKeyFCH",
"_tKeypadFC",
"_tKeypadFCH",
"_tKeypadTC"
};
int Options::getID(string name){
if(!name.size())
INVALID_OPTION;
std::transform(name.begin(),name.end(),name.begin(),::tolower);
//Is it a named option?
for(int x = 0; x < LAST_NAMED; x++){
string lower = Options::optionNames[x];
std::transform(lower.begin(),lower.end(),lower.begin(),::tolower);
if(lower == name)
return x;
}
//Is it an unlocked set?
if(MtgSets::SetsList){
int unlocked = MtgSets::SetsList->find(name);
if(unlocked != -1)
return Options::optionSet(unlocked);
}
//Failure.
return INVALID_OPTION;
}
string Options::getName(int option){
//Invalid options
if(option < 0)
return "";
//Standard named options
if(option < LAST_NAMED)
return optionNames[option];
//Unlocked sets.
if(MtgSets::SetsList){
int setID = option - SET_UNLOCKS;
if(setID >= 0 && setID < MtgSets::SetsList->nb_items){
char buf[512];
sprintf(buf,"unlocked_%s",MtgSets::SetsList->values[setID].c_str());
return buf;
}
}
//Failed.
return "";
}
int Options::optionSet(int setID){
//Sanity check if possible
if(setID < 0 || (MtgSets::SetsList && setID > MtgSets::SetsList->nb_items))
return INVALID_OPTION;
return SET_UNLOCKS + setID;
}
int Options::optionInterrupt(int gamePhase){
//Huge, nearly illegible switch block spread out to improve readability.
switch(gamePhase){
case Constants::MTG_PHASE_BEFORE_BEGIN:
return INTERRUPT_BEFOREBEGIN;
case Constants::MTG_PHASE_UNTAP:
return INTERRUPT_UNTAP;
case Constants::MTG_PHASE_UPKEEP:
return INTERRUPT_UPKEEP;
case Constants::MTG_PHASE_DRAW:
return INTERRUPT_DRAW;
case Constants::MTG_PHASE_FIRSTMAIN:
return INTERRUPT_FIRSTMAIN;
case Constants::MTG_PHASE_COMBATBEGIN:
return INTERRUPT_BEGINCOMBAT;
case Constants::MTG_PHASE_COMBATATTACKERS:
return INTERRUPT_ATTACKERS;
case Constants::MTG_PHASE_COMBATBLOCKERS:
return INTERRUPT_BLOCKERS;
case Constants::MTG_PHASE_COMBATDAMAGE:
return INTERRUPT_DAMAGE;
case Constants::MTG_PHASE_COMBATEND:
return INTERRUPT_ENDCOMBAT;
case Constants::MTG_PHASE_SECONDMAIN:
return INTERRUPT_SECONDMAIN;
case Constants::MTG_PHASE_ENDOFTURN:
return INTERRUPT_ENDTURN;
case Constants::MTG_PHASE_CLEANUP:
return INTERRUPT_CLEANUP;
case Constants::MTG_PHASE_AFTER_EOT:
return INTERRUPT_AFTEREND;
}
return INVALID_OPTION;
}
//Theme metrics
/*
const string Metrics::LOADING_TC = "_tLoadingTC"; const string Metrics::LOADING_TC = "_tLoadingTC";
const string Metrics::STATS_TC = "_tStatsTC"; const string Metrics::STATS_TC = "_tStatsTC";
const string Metrics::SCROLLER_TC = "_tScrollerTC"; const string Metrics::SCROLLER_TC = "_tScrollerTC";
@@ -73,7 +212,7 @@ const string Metrics::KEY_FC = "_tKeyFC";
const string Metrics::KEY_FCH = "_tKeyFCH"; const string Metrics::KEY_FCH = "_tKeyFCH";
const string Metrics::KEYPAD_FC = "_tKeypadFC"; const string Metrics::KEYPAD_FC = "_tKeypadFC";
const string Metrics::KEYPAD_FCH = "_tKeypadFCH"; const string Metrics::KEYPAD_FCH = "_tKeypadFCH";
const string Metrics::KEYPAD_TC = "_tKeypadTC"; const string Metrics::KEYPAD_TC = "_tKeypadTC"; */
GameOption::GameOption(int value) : number(value){} GameOption::GameOption(int value) : number(value){}
@@ -130,6 +269,59 @@ GameOptions::GameOptions(string filename){
mFilename = filename; mFilename = filename;
load(); load();
} }
bool GameOptions::read_default(int id, string input){
bool bNumeric = true;
if(!input.size()){
values[id] = GameOption(0);
return true; //Default reader doesn't care about invalid formatting.
}
//Is it a number?
for(size_t x=0;x<input.size();x++) {
if(!isdigit(input[x])) {
bNumeric = false;
break;
}
}
if(bNumeric)
values[id] = GameOption(atoi(input.c_str()));
else
values[id] = GameOption(input);
return true;
}
bool GameOptions::read_enum(int id, string input, EnumDefinition * def){
if(!def)
return false;
std::transform(input.begin(),input.end(),input.begin(),::tolower);
vector<EnumDefinition::assoc>::iterator it;
for(it=def->values.begin();it != def->values.end();it++){
if(it->second == input){
values[id] = GameOption(it->first);
return true;
}
}
return false;
}
bool GameOptions::load_option(int id, string input){
switch(id){
case Options::HANDDIRECTION:
return read_enum(id, input, OptionHandDirection::getDefinition());
case Options::CLOSEDHAND:
return read_enum(id, input, OptionClosedHand::getDefinition());
default:
return read_default(id, input);
}
return false;
}
int GameOptions::load(){ int GameOptions::load(){
std::ifstream file(mFilename.c_str()); std::ifstream file(mFilename.c_str());
std::string s; std::string s;
@@ -137,47 +329,91 @@ int GameOptions::load(){
if(file){ if(file){
while(std::getline(file,s)){ while(std::getline(file,s)){
int found =s.find("="); int found =s.find("=");
bool bnumber = true;
string name = s.substr(0,found); string name = s.substr(0,found);
string val = s.substr(found+1); string val = s.substr(found+1);
for(size_t x=0;x<val.size();x++) { int id = Options::getID(name);
if(!isdigit(val[x])) { if(id == INVALID_OPTION)
bnumber = false; continue;
break;
} load_option(id,val);
}
if(bnumber)
values[name] = GameOption(atoi(val.c_str()));
else
values[name] = GameOption(val);
} }
file.close(); file.close();
} }
return 1; return 1;
} }
bool GameOptions::save_option(std::ofstream * file, int id, string name, GameOption * opt){
if(!opt)
return false;
switch(id){
case Options::HANDDIRECTION:
return write_enum(file, name, opt, OptionHandDirection::getDefinition());
case Options::CLOSEDHAND:
return write_enum(file, name, opt, OptionClosedHand::getDefinition());
default:
return write_default(file, name, opt);
}
return false;
}
bool GameOptions::write_default(std::ofstream * file, string name, GameOption * opt){
char writer[1024];
if(!file || !opt)
return false;
if(opt->str ==""){
if(opt->number == 0) //This is absolutely default. No need to write it.
return true;
//It's a number!
sprintf(writer,"%s=%d\n", name.c_str(), opt->number);
}
else
sprintf(writer,"%s=%s\n", name.c_str(), opt->str.c_str());
(*file)<<writer;
return true;
}
bool GameOptions::write_enum(std::ofstream * file, string name, GameOption * opt, EnumDefinition * def){
if(!file || !def || !opt)
return false;
if(opt->number < 0 || opt->number >= (int) def->values.size())
return false;
char writer[1024];
sprintf(writer,"%s=%s\n", name.c_str(), def->values[opt->number].second.c_str());
(*file)<<writer;
return true;
}
int GameOptions::save(){ int GameOptions::save(){
std::ofstream file(mFilename.c_str()); std::ofstream file(mFilename.c_str());
char writer[1024];
if (file){ if (file){
map<string, GameOption>::iterator it; map<int, GameOption>::iterator it;
for ( it=values.begin() ; it != values.end(); it++ ){ for ( it=values.begin() ; it != values.end(); it++ ){
if(it->second.str ==""){
sprintf(writer,"%s=%d\n", it->first.c_str(), it->second.number); //Check that this is a valid option.
if(it->second.number==0) string name = Options::getName(it->first);
if(!name.size())
continue; continue;
}
else //Save it.
sprintf(writer,"%s=%s\n", it->first.c_str(), it->second.str.c_str()); save_option(&file, it->first, name, &it->second);
file<<writer;
} }
file.close(); file.close();
} }
return 1; return 1;
} }
GameOption& GameOptions::operator[](string option_name) { GameOption& GameOptions::operator[](int optionID) {
return values[option_name]; return values[optionID];
} }
GameOptions::~GameOptions(){ GameOptions::~GameOptions(){
@@ -206,19 +442,35 @@ GameSettings::~GameSettings(){
SAFE_DELETE(globalOptions); SAFE_DELETE(globalOptions);
SAFE_DELETE(profileOptions); SAFE_DELETE(profileOptions);
SAFE_DELETE(themeOptions); SAFE_DELETE(themeOptions);
SAFE_DELETE(OptionHandDirection::definition);
SAFE_DELETE(OptionClosedHand::definition);
}
GameOption GameSettings::invalid_option = GameOption(0);
GameOption& GameSettings::operator[](int optionID){
string option_name = Options::getName(optionID);
//Last chance sanity checking.
if(!option_name.size()){
OutputDebugString("Error: Accessing invalid option.\n");
invalid_option.number = 0;
invalid_option.str = "";
return invalid_option;
} }
GameOption& GameSettings::operator[](string option_name){
if(option_name.size() > 2){ if(option_name.size() > 2){
if(option_name[0] == '_' && option_name[1] == 't') if(option_name[0] == '_' && option_name[1] == 't')
return (*themeOptions)[option_name.substr(2)]; return (*themeOptions)[optionID];
else if(option_name[0] == '_' && option_name[1] == 'g') else if(option_name[0] == '_' && option_name[1] == 'g')
return (*globalOptions)[option_name.substr(2)]; return (*globalOptions)[optionID];
} }
return (*profileOptions)[option_name]; return (*profileOptions)[optionID];
} }
int GameSettings::save(){ int GameSettings::save(){
if(globalOptions) if(globalOptions)
globalOptions->save(); globalOptions->save();
@@ -308,7 +560,7 @@ void GameSettings::checkProfile(){
if(theGame == NULL || theGame->collection == NULL) if(theGame == NULL || theGame->collection == NULL)
return; return;
string pcFile = profileFile(PLAYER_COLLECTION); string pcFile = profileFile(PLAYER_COLLECTION,"",false);
if(!pcFile.size() || !fileExists(pcFile.c_str())) if(!pcFile.size() || !fileExists(pcFile.c_str()))
{ {
//If we had any default settings, we'd set them here. //If we had any default settings, we'd set them here.
@@ -324,11 +576,21 @@ void GameSettings::checkProfile(){
} }
} }
//Make the proper directories
if(profileOptions){
//Force our directories to exist.
MAKEDIR(RESPATH"/profiles");
string temp = profileFile("","",false,false);
MAKEDIR(temp.c_str());
temp+="/stats";
MAKEDIR(temp.c_str());
temp = profileFile(PLAYER_SETTINGS,"",false);
profileOptions->save();
}
//Save this set as "unlocked" //Save this set as "unlocked"
char buffer[4096]; (*profileOptions)[Options::optionSet(setId)]=1;
string s = MtgSets::SetsList->values[setId];
sprintf(buffer,"unlocked_%s", s.c_str());
(*profileOptions)[buffer]=1;
profileOptions->save(); profileOptions->save();
//Give the player their first deck //Give the player their first deck
@@ -411,3 +673,13 @@ string GameSettings::keypadFinish(){
void GameSettings::keypadShutdown(){ void GameSettings::keypadShutdown(){
SAFE_DELETE(keypad); SAFE_DELETE(keypad);
} }
int EnumDefinition::findIndex(int value){
vector<assoc>::iterator it;
for(it = values.begin();it!=values.end();it++){
if(it->first == value)
return it - values.begin();
}
return 0; //Default!
}
+1 -4
View File
@@ -188,7 +188,6 @@ void GameStateMenu::fillScroller(){
int totalGames = 0; int totalGames = 0;
for (int j=1; j<6; j++){ for (int j=1; j<6; j++){
sprintf(buffer, "stats/player_deck%i.txt",j); sprintf(buffer, "stats/player_deck%i.txt",j);
string deckstats = options.profileFile(buffer); string deckstats = options.profileFile(buffer);
if(fileExists(deckstats.c_str())){ if(fileExists(deckstats.c_str())){
@@ -224,9 +223,7 @@ void GameStateMenu::fillScroller(){
//Unlocked sets //Unlocked sets
int nbunlocked = 0; int nbunlocked = 0;
for (int i = 0; i < MtgSets::SetsList->nb_items; i++){ for (int i = 0; i < MtgSets::SetsList->nb_items; i++){
string s = MtgSets::SetsList->values[i]; if (1 == options[Options::optionSet(i)].number) nbunlocked++;
sprintf(buffer,"unlocked_%s", s.c_str());
if (1 == options[buffer].number) nbunlocked++;
} }
sprintf(buff2, _("You have unlocked %i expansions out of %i").c_str(),nbunlocked, MtgSets::SetsList->nb_items); sprintf(buff2, _("You have unlocked %i expansions out of %i").c_str(),nbunlocked, MtgSets::SetsList->nb_items);
scroller->Add(buff2); scroller->Add(buff2);
+1 -1
View File
@@ -48,7 +48,7 @@ void GameStateOptions::Start()
optionsTabs->Add(optionsList); optionsTabs->Add(optionsList);
optionsList = NEW OptionsList("Profiles"); optionsList = NEW OptionsList("Profiles");
OptionNewProfile * key = NEW OptionNewProfile("","New Profile"); OptionNewProfile * key = NEW OptionNewProfile("New Profile");
key->bShowValue = false; key->bShowValue = false;
optionsList->Add(key); optionsList->Add(key);
OptionProfile * pickProf = NEW OptionProfile(mParent); OptionProfile * pickProf = NEW OptionProfile(mParent);
+3 -7
View File
@@ -71,18 +71,14 @@ void GameStateShop::load(){
for (int i = 0; i < MtgSets::SetsList->nb_items; i++){ for (int i = 0; i < MtgSets::SetsList->nb_items; i++){
string s = MtgSets::SetsList->values[i]; string s = MtgSets::SetsList->values[i];
if (s.compare("10E") == 0) defaultSet = i; if (s.compare("10E") == 0) defaultSet = i;
char buffer[4096];
sprintf(buffer,"unlocked_%s", s.c_str()); unlocked[i] = options[Options::optionSet(i)].number;
unlocked[i] = options[buffer].number;
if (unlocked[i]) if (unlocked[i])
ok = 1; ok = 1;
} }
if (!ok){ if (!ok){
unlocked[defaultSet] = 1; unlocked[defaultSet] = 1;
string s = MtgSets::SetsList->values[defaultSet]; options[Options::optionSet(defaultSet)] = GameOption(1);
char buffer[4096];
sprintf(buffer,"unlocked_%s", s.c_str());
options[buffer] = GameOption(1);
options.save(); options.save();
} }
+67 -28
View File
@@ -1,8 +1,6 @@
#include "../include/config.h" #include "../include/config.h"
#include "../include/OptionItem.h" #include "../include/OptionItem.h"
#include "../include/GameApp.h"
#include <JGE.h> #include <JGE.h>
#include "../include/GameOptions.h"
#include "../include/PlayerData.h" #include "../include/PlayerData.h"
#include "../include/Translate.h" #include "../include/Translate.h"
#include <dirent.h> #include <dirent.h>
@@ -34,7 +32,7 @@ return out << "OptionItem ::: displayValue : " << displayValue
<< " ; x,y : " << x << "," << y; << " ; x,y : " << x << "," << y;
} }
OptionItem::OptionItem( string _id, string _displayValue) { OptionItem::OptionItem( int _id, string _displayValue) {
id = _id; id = _id;
displayValue = _(_displayValue); displayValue = _(_displayValue);
canSelect=true; canSelect=true;
@@ -72,7 +70,7 @@ void OptionInteger::Render(){
mFont->DrawString(buf,width -10 ,y,JGETEXT_RIGHT); mFont->DrawString(buf,width -10 ,y,JGETEXT_RIGHT);
} }
OptionInteger::OptionInteger(string _id, string _displayValue, int _maxValue, int _increment, int _defV, string _sDef): OptionItem(_id, _displayValue){ OptionInteger::OptionInteger(int _id, string _displayValue, int _maxValue, int _increment, int _defV, string _sDef): OptionItem(_id, _displayValue){
defValue = _defV; defValue = _defV;
strDefault = _sDef; strDefault = _sDef;
maxValue = _maxValue; maxValue = _maxValue;
@@ -84,7 +82,7 @@ OptionInteger::OptionInteger(string _id, string _displayValue, int _maxValue, in
} }
void OptionInteger::setData(){ void OptionInteger::setData(){
if(id != "") if(id != INVALID_OPTION)
options[id] = GameOption(value); options[id] = GameOption(value);
} }
@@ -130,7 +128,8 @@ void OptionSelect::Render(){
void OptionSelect::setData() void OptionSelect::setData()
{ {
if(id == "") return; if(id == INVALID_OPTION) return;
if (value < selections.size()) if (value < selections.size())
options[id] = GameOption(selections[value]); options[id] = GameOption(selections[value]);
} }
@@ -356,7 +355,7 @@ void OptionDirectory::Reload(){
initSelections(); initSelections();
} }
OptionDirectory::OptionDirectory(string _root, string _id, string _displayValue): OptionSelect(_id, _displayValue){ OptionDirectory::OptionDirectory(string _root, int _id, string _displayValue): OptionSelect(_id, _displayValue){
DIR *mDip; DIR *mDip;
struct dirent *mDit; struct dirent *mDit;
char buf[4096]; char buf[4096];
@@ -741,7 +740,7 @@ void OptionString::Render(){
} }
void OptionString::setData(){ void OptionString::setData(){
if(id != "") if(id != INVALID_OPTION)
options[id] = GameOption(value); options[id] = GameOption(value);
} }
void OptionString::updateValue(){ void OptionString::updateValue(){
@@ -780,10 +779,10 @@ int OptionNewProfile::Submode(){
return OPTIONS_SUBMODE_NORMAL; return OPTIONS_SUBMODE_NORMAL;
} }
OptionString::OptionString(string _id, string _displayValue): OptionItem(_id, _displayValue) OptionString::OptionString(int _id, string _displayValue): OptionItem(_id, _displayValue)
{ {
bShowValue=true; bShowValue=true;
if(_id != "") if(id != INVALID_OPTION)
value=options[_id].str; value=options[_id].str;
} }
@@ -810,23 +809,31 @@ void OptionVolume::updateValue(){
value=0; value=0;
} }
OptionVolume::OptionVolume(string id, string displayName, bool music): OptionInteger(id, displayName, 100, 10, 0, "Muted") { OptionVolume::OptionVolume(int id, string displayName, bool music): OptionInteger(id, displayName, 100, 10, 0, "Muted") {
bMusic = music; bMusic = music;
} }
void OptionEnum::setData() void OptionEnum::setData()
{ {
options[id] = GameOption(values[index].first, values[index].second); EnumDefinition * def = ourDefined();
if(def)
options[id] = GameOption(def->values[index].first);
} }
void OptionEnum::updateValue() void OptionEnum::updateValue()
{ {
EnumDefinition * def = ourDefined();
if(!def)
return;
++index; ++index;
if (index >= values.size()) index = 0; if (index >= def->values.size()) index = 0;
} }
void OptionEnum::Render() void OptionEnum::Render()
{ {
EnumDefinition * def = ourDefined();
JLBFont * mFont = resources.GetJLBFont("f3"); JLBFont * mFont = resources.GetJLBFont("f3");
if (hasFocus) if (hasFocus)
mFont->SetColor(options[Metrics::OPTION_ITEM_TCH].asColor(ARGB(255,255,255,0))); mFont->SetColor(options[Metrics::OPTION_ITEM_TCH].asColor(ARGB(255,255,255,0)));
@@ -835,34 +842,66 @@ void OptionEnum::Render()
JRenderer * renderer = JRenderer::GetInstance(); JRenderer * renderer = JRenderer::GetInstance();
renderer->FillRoundRect(x-5,y-2,width-x-5,height,2,options[Metrics::OPTION_ITEM_FC].asColor(ARGB(150,50,50,50))); renderer->FillRoundRect(x-5,y-2,width-x-5,height,2,options[Metrics::OPTION_ITEM_FC].asColor(ARGB(150,50,50,50)));
mFont->DrawString(displayValue.c_str(),x,y); mFont->DrawString(displayValue.c_str(),x,y);
mFont->DrawString(values[index].second.c_str(), width -10, y, JGETEXT_RIGHT);
}
if(def)
mFont->DrawString(def->values[index].second.c_str(), width -10, y, JGETEXT_RIGHT);
else
mFont->DrawString("Default", width -10, y, JGETEXT_RIGHT);
}
OptionEnum::OptionEnum(int id, string displayValue) : OptionItem(id, displayValue){
Reload();
}
void OptionEnum::Reload() void OptionEnum::Reload()
{ {
for (vector<assoc>::iterator it = values.begin(); it != values.end(); ++it) EnumDefinition * def = ourDefined();
if (it->second == options[id].str) if(def != NULL)
{ index = def->findIndex(options[id].number);
index = it - values.begin();
return;
} }
index = 0;
EnumDefinition * OptionEnum::getDefinition(){
return NULL;
} }
ostream& OptionEnum::toString(ostream& out) const ostream& OptionEnum::toString(ostream& out) const
{ {
return (out << values[index].second); EnumDefinition * def = ourDefined();
if(!def)
return (out << "OptionEnum ::: INVALID");
return (out << "OptionEnum ::: " << def->values[index].second);
} }
OptionClosedHand::OptionClosedHand(string id, string displayName) : OptionEnum(id, displayName) EnumDefinition * OptionClosedHand::definition = NULL;
EnumDefinition * OptionClosedHand::getDefinition(){
if(!definition){
definition = NEW EnumDefinition();
definition->values.push_back(EnumDefinition::assoc(INVISIBLE, "invisible"));
definition->values.push_back(EnumDefinition::assoc(VISIBLE, "visible"));
}
return definition;
}
OptionClosedHand::OptionClosedHand(int id, string displayName) : OptionEnum(id, displayName)
{ {
values.push_back(assoc(INVISIBLE, "invisible")); getDefinition();
values.push_back(assoc(VISIBLE, "visible"));
Reload(); Reload();
}; };
OptionHandDirection::OptionHandDirection(string id, string displayName) : OptionEnum(id, displayName)
EnumDefinition * OptionHandDirection::definition = NULL;
EnumDefinition * OptionHandDirection::getDefinition(){
if(!definition){
definition = NEW EnumDefinition();
definition->values.push_back(EnumDefinition::assoc(VERTICAL, "vertical"));
definition->values.push_back(EnumDefinition::assoc(HORIZONTAL, "horizontal"));
}
return definition;
}
OptionHandDirection::OptionHandDirection(int id, string displayName) : OptionEnum(id, displayName)
{ {
values.push_back(assoc(VERTICAL, "vertical")); getDefinition();
values.push_back(assoc(HORIZONTAL, "horizontal"));
Reload(); Reload();
}; };