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

View File

@@ -1,46 +1,46 @@
#ifndef _CREDITS_H_
#define _CREDITS_H_
#include <vector>
#include <string>
#include <JGE.h>
#include <JLBFont.h>
#include "../include/Player.h"
class GameApp;
using namespace std;
class CreditBonus{
public:
int value;
string text;
CreditBonus(int _value, string _text);
void Render(float x, float y, JLBFont * font);
};
class Credits{
private:
int isDifficultyUnlocked();
int isMomirUnlocked();
int isEvilTwinUnlocked();
int isRandomDeckUnlocked();
int unlockRandomSet();
public:
int value;
Player * p1, *p2;
GameApp * app;
int showMsg;
int unlocked;
JQuad * unlockedQuad;
JTexture * unlockedTex;
string unlockedString;
vector<CreditBonus *> bonus;
Credits();
~Credits();
void compute(Player * _p1, Player * _p2, GameApp * _app);
void Render();
};
#ifndef _CREDITS_H_
#define _CREDITS_H_
#include <vector>
#include <string>
#include <JGE.h>
#include <JLBFont.h>
#include "../include/Player.h"
class GameApp;
using namespace std;
class CreditBonus{
public:
int value;
string text;
CreditBonus(int _value, string _text);
void Render(float x, float y, JLBFont * font);
};
class Credits{
private:
int isDifficultyUnlocked();
int isMomirUnlocked();
int isEvilTwinUnlocked();
int isRandomDeckUnlocked();
int unlockRandomSet();
public:
int value;
Player * p1, *p2;
GameApp * app;
int showMsg;
int unlocked;
JQuad * unlockedQuad;
JTexture * unlockedTex;
string unlockedString;
vector<CreditBonus *> bonus;
Credits();
~Credits();
void compute(Player * _p1, Player * _p2, GameApp * _app);
void Render();
};
#endif

View File

@@ -14,25 +14,95 @@ using std::string;
#define PLAYER_SETTINGS "options.txt"
#define PLAYER_COLLECTION "collection.dat"
struct Options {
static const string MUSICVOLUME;
static const string SFXVOLUME;
static const string DIFFICULTY_MODE_UNLOCKED;
static const string MOMIR_MODE_UNLOCKED;
static const string EVILTWIN_MODE_UNLOCKED;
static const string RANDOMDECK_MODE_UNLOCKED;
static const string DIFFICULTY;
static const string CACHESIZE;
static const string PLASMAEFFECT;
static const string INTERRUPT_SECONDS;
static const string INTERRUPTMYSPELLS;
static const string INTERRUPTMYABILITIES;
static const string OSD;
static const string ACTIVE_PROFILE;
static const string ACTIVE_THEME;
static const string ACTIVE_MODE;
static const string CLOSEDHAND;
static const string HANDDIRECTION;
#define INVALID_OPTION -1
//Note to self-- provide some form of options initialization.
class Options {
public:
friend class GameSettings;
enum {
//Values /must/ match ordering in optionNames, or everything loads wrong.
//Profile settings
ACTIVE_THEME,
ACTIVE_MODE,
MUSICVOLUME,
SFXVOLUME,
DIFFICULTY,
PLASMAEFFECT,
OSD,
CLOSEDHAND,
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 {
@@ -40,35 +110,37 @@ struct Metrics {
//*_FC is fill-color, *_FCH is highlighted fill color
//*_B and *_BH are for secondary text/fill colors, if needed
//*_X, *_Y, *_W, *_H are x, y, width and height.
static const string LOADING_TC;
static const string STATS_TC;
static const string SCROLLER_TC;
static const string SCROLLER_FC;
static const string MAINMENU_TC;
static const string POPUP_MENU_FC;
static const string POPUP_MENU_TC;
static const string POPUP_MENU_TCH;
static const string MSG_FAIL_TC;
static const string OPTION_ITEM_FC;
static const string OPTION_ITEM_TC;
static const string OPTION_ITEM_TCH;
static const string OPTION_HEADER_FC;
static const string OPTION_HEADER_TC;
static const string OPTION_SCROLLBAR_FC;
static const string OPTION_SCROLLBAR_FCH;
static const string OPTION_TAB_FC;
static const string OPTION_TAB_FCH;
static const string OPTION_TAB_TC;
static const string OPTION_TAB_TCH;
static const string OPTION_TEXT_TC;
static const string OPTION_TEXT_FC;
static const string KEY_TC;
static const string KEY_TCH;
static const string KEY_FC;
static const string KEY_FCH;
static const string KEYPAD_FC;
static const string KEYPAD_FCH;
static const string KEYPAD_TC;
enum {
LOADING_TC = Options::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,
};
};
class GameOption {
@@ -83,6 +155,12 @@ public:
GameOption(int, string);
};
struct EnumDefinition {
int findIndex(int value);
typedef pair<int, string> assoc;
vector<assoc> values;
};
class GameOptions {
public:
@@ -90,13 +168,20 @@ class GameOptions {
int save();
int load();
static const char * phaseInterrupts[];
GameOption& operator[](string);
GameOption& operator[](int);
GameOptions(string filename);
~GameOptions();
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{
@@ -124,11 +209,13 @@ public:
void checkProfile(); //Confirms that a profile is loaded and contains a collection.
void createUsersFirstDeck(int setId);
GameOption& operator[](string);
GameOption& operator[](int);
GameOptions* profileOptions;
GameOptions* globalOptions;
GameOptions* themeOptions;
static GameOption invalid_option;
private:
GameApp * theGame;
SimplePad * keypad;

View File

@@ -5,6 +5,7 @@
#include <vector>
#include <string>
#include "../include/GameApp.h"
#include "../include/GameOptions.h"
using std::string;
@@ -21,7 +22,8 @@ using std::string;
class OptionItem {
public:
string displayValue, id;
string displayValue;
int id;
int hasFocus;
bool canSelect;
bool bHidden;
@@ -29,7 +31,7 @@ public:
float width, height;
virtual ostream& toString(ostream& out)const;
OptionItem( string _id, string _displayValue);
OptionItem( int _id, string _displayValue);
virtual ~OptionItem() {};
virtual bool Selectable() {return (canSelect && !bHidden);};
@@ -52,9 +54,9 @@ class OptionInteger:public OptionItem{
string strDefault; //What to call the default value.
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 setData();
virtual void updateValue(){value+=increment; if (value>maxValue) value=0;};
@@ -64,19 +66,19 @@ class OptionInteger:public OptionItem{
class OptionString:public OptionItem{
public:
string value;
OptionString(string _id, string _displayValue);
OptionString(int _id, string _displayValue);
virtual void Render();
virtual void setData();
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;
bool bShowValue;
};
class OptionNewProfile:public OptionString{
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 Update(float dt);
virtual int Submode();
@@ -85,7 +87,7 @@ class OptionNewProfile:public OptionString{
class OptionHeader:public OptionItem{
public:
OptionHeader(string _displayValue): OptionItem("", _displayValue) { canSelect=false;};
OptionHeader(string _displayValue): OptionItem(INVALID_OPTION, _displayValue) { canSelect=false;};
virtual void Render();
virtual void setData() {};
virtual void updateValue() {};
@@ -93,7 +95,7 @@ class OptionHeader:public OptionItem{
class OptionText:public OptionItem{
public:
OptionText(string _displayValue): OptionItem("", _displayValue) { canSelect=false;};
OptionText(string _displayValue): OptionItem(INVALID_OPTION, _displayValue) { canSelect=false;};
virtual void Render();
virtual void setData() {};
virtual void updateValue() {};
@@ -105,7 +107,7 @@ class OptionSelect:public OptionItem{
vector<string> selections;
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 Render();
virtual void setData();
@@ -118,7 +120,7 @@ class OptionSelect:public OptionItem{
class OptionDirectory:public OptionSelect{
public:
virtual void Reload();
OptionDirectory(string _root, string _id, string _displayValue);
OptionDirectory(string _root, int _id, string _displayValue);
private:
string root;
};
@@ -130,7 +132,7 @@ class OptionTheme:public OptionDirectory{
class OptionVolume: public OptionInteger{
public:
OptionVolume(string _id, string _displayName, bool _bMusic = false);
OptionVolume(int _id, string _displayName, bool _bMusic = false);
virtual void updateValue();
private:
bool bMusic;
@@ -208,27 +210,43 @@ class OptionsMenu
class OptionEnum : public OptionItem {
protected:
typedef pair<int, string> assoc;
unsigned index;
vector<assoc> values;
public:
OptionEnum(string id, string displayValue) : OptionItem(id, displayValue), index(0) {};
OptionEnum(int id, string displayValue);
virtual void Reload();
virtual void Render();
virtual void setData();
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;
};
class OptionClosedHand : public OptionEnum {
public:
friend class GameSettings;
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 {
public:
friend class GameSettings;
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

View File

@@ -103,10 +103,7 @@ void Credits::compute(Player * _p1, Player * _p2, GameApp * _app){
}else if((unlocked = unlockRandomSet())) {
unlockedTex = resources.RetrieveTexture("set_unlocked.png", RETRIEVE_VRAM);
unlockedQuad = resources.RetrieveQuad("set_unlocked.png", 2, 2, 396, 96);
char buffer[4096];
unlockedString = MtgSets::SetsList->values[unlocked -1];
sprintf(buffer,"unlocked_%s", unlockedString.c_str());
options[buffer] = GameOption(1);
options[Options::optionSet(unlocked - 1)] = GameOption(1);
options.save();
}
if (unlocked){
@@ -239,9 +236,9 @@ int Credits::isRandomDeckUnlocked(){
int Credits::unlockRandomSet(){
if (rand() % 2) return 0;
int setId = rand() % MtgSets::SetsList->nb_items;
char buffer[4096];
string s = MtgSets::SetsList->values[setId];
sprintf(buffer,"unlocked_%s", s.c_str());
if (1 == options[buffer].number) return 0;
return setId + 1;
if (1 == options[Options::optionSet(setId)].number)
return 0;
return setId + 1; //We add 1 here to show success/failure. Be sure to subtract later.
}

View File

@@ -165,13 +165,13 @@ void GameObserver::userRequestNextGamePhase(){
Phase * cPhaseOld = phaseRing->getCurrentPhase();
if ((cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) ||
cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE ||
opponent()->isAI() ||
options[GameOptions::phaseInterrupts[currentGamePhase]].number)
mLayers->stackLayer()->AddNextGamePhase();
else
nextGamePhase();
if ((cPhaseOld->id == Constants::MTG_PHASE_COMBATBLOCKERS && combatStep == ORDER) ||
cPhaseOld->id == Constants::MTG_PHASE_COMBATDAMAGE ||
opponent()->isAI() ||
options[Options::optionInterrupt(currentGamePhase)].number)
mLayers->stackLayer()->AddNextGamePhase();
else
nextGamePhase();
}

View File

@@ -2,49 +2,188 @@
#include "../include/utils.h"
#include "../include/MTGDeck.h"
#include "../include/GameOptions.h"
#include "../include/OptionItem.h"
#include <iostream>
#include <fstream>
#include <string>
#include <stdlib.h>
#include <JGE.h>
const char* GameOptions::phaseInterrupts[] = {
"interrupt ---",
"interrupt Untap",
"interrupt Upkeep",
"interrupt Draw",
"interrupt Main phase 1",
"interrupt Combat begins",
"interrupt Attackers",
"interrupt Blockers",
"interrupt Combat damage",
"interrupt Combat ends",
"interrupt Main phase 2",
"interrupt End of turn",
"interrupt Cleanup",
"interrupt ---"
};
//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";
const char * Options::optionNames[] = {
//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",
"interruptUpkeep",
"interruptDraw",
"interruptFirstMain",
"interruptBeginCombat",
"interruptAttackers",
"interruptBlockers",
"interruptDamage",
"interruptEndCombat",
"interruptSecondMain",
"interruptEndTurn",
"interruptCleanup",
"interruptAfterEnd",
//Global options
const string Options::ACTIVE_PROFILE = "_gProfile";
const string Options::DIFFICULTY_MODE_UNLOCKED = "_gprx_handler"; //huhu
const string Options::MOMIR_MODE_UNLOCKED = "_gprx_rimom"; //haha
const string Options::EVILTWIN_MODE_UNLOCKED = "_gprx_eviltwin";
const string Options::RANDOMDECK_MODE_UNLOCKED = "_gprx_rnddeck";
const string Options::CACHESIZE = "_gcacheSize";
const string Options::CLOSEDHAND = "closed_hand";
const string Options::HANDDIRECTION = "hand_direction";
"_gProfile",
"_gprx_handler",
"_gprx_rimom",
"_gprx_eviltwin",
"_gprx_rnddeck",
"_gcacheSize",
//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::STATS_TC = "_tStatsTC";
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::KEYPAD_FC = "_tKeypadFC";
const string Metrics::KEYPAD_FCH = "_tKeypadFCH";
const string Metrics::KEYPAD_TC = "_tKeypadTC";
const string Metrics::KEYPAD_TC = "_tKeypadTC"; */
GameOption::GameOption(int value) : number(value){}
@@ -130,6 +269,59 @@ GameOptions::GameOptions(string filename){
mFilename = filename;
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(){
std::ifstream file(mFilename.c_str());
std::string s;
@@ -137,47 +329,91 @@ int GameOptions::load(){
if(file){
while(std::getline(file,s)){
int found =s.find("=");
bool bnumber = true;
string name = s.substr(0,found);
string val = s.substr(found+1);
for(size_t x=0;x<val.size();x++) {
if(!isdigit(val[x])) {
bnumber = false;
break;
}
}
if(bnumber)
values[name] = GameOption(atoi(val.c_str()));
else
values[name] = GameOption(val);
int id = Options::getID(name);
if(id == INVALID_OPTION)
continue;
load_option(id,val);
}
file.close();
}
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(){
std::ofstream file(mFilename.c_str());
char writer[1024];
if (file){
map<string, GameOption>::iterator it;
map<int, GameOption>::iterator 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);
if(it->second.number==0)
continue;
}
else
sprintf(writer,"%s=%s\n", it->first.c_str(), it->second.str.c_str());
file<<writer;
//Check that this is a valid option.
string name = Options::getName(it->first);
if(!name.size())
continue;
//Save it.
save_option(&file, it->first, name, &it->second);
}
file.close();
file.close();
}
return 1;
}
GameOption& GameOptions::operator[](string option_name) {
return values[option_name];
GameOption& GameOptions::operator[](int optionID) {
return values[optionID];
}
GameOptions::~GameOptions(){
@@ -206,19 +442,35 @@ GameSettings::~GameSettings(){
SAFE_DELETE(globalOptions);
SAFE_DELETE(profileOptions);
SAFE_DELETE(themeOptions);
SAFE_DELETE(OptionHandDirection::definition);
SAFE_DELETE(OptionClosedHand::definition);
}
GameOption& GameSettings::operator[](string option_name){
if(option_name.size() > 2){
if(option_name[0] == '_' && option_name[1] == 't')
return (*themeOptions)[option_name.substr(2)];
else if(option_name[0] == '_' && option_name[1] == 'g')
return (*globalOptions)[option_name.substr(2)];
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;
}
return (*profileOptions)[option_name];
if(option_name.size() > 2){
if(option_name[0] == '_' && option_name[1] == 't')
return (*themeOptions)[optionID];
else if(option_name[0] == '_' && option_name[1] == 'g')
return (*globalOptions)[optionID];
}
return (*profileOptions)[optionID];
}
int GameSettings::save(){
if(globalOptions)
globalOptions->save();
@@ -308,7 +560,7 @@ void GameSettings::checkProfile(){
if(theGame == NULL || theGame->collection == NULL)
return;
string pcFile = profileFile(PLAYER_COLLECTION);
string pcFile = profileFile(PLAYER_COLLECTION,"",false);
if(!pcFile.size() || !fileExists(pcFile.c_str()))
{
//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"
char buffer[4096];
string s = MtgSets::SetsList->values[setId];
sprintf(buffer,"unlocked_%s", s.c_str());
(*profileOptions)[buffer]=1;
(*profileOptions)[Options::optionSet(setId)]=1;
profileOptions->save();
//Give the player their first deck
@@ -411,3 +673,13 @@ string GameSettings::keypadFinish(){
void GameSettings::keypadShutdown(){
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!
}

View File

@@ -188,7 +188,6 @@ void GameStateMenu::fillScroller(){
int totalGames = 0;
for (int j=1; j<6; j++){
sprintf(buffer, "stats/player_deck%i.txt",j);
string deckstats = options.profileFile(buffer);
if(fileExists(deckstats.c_str())){
@@ -224,9 +223,7 @@ void GameStateMenu::fillScroller(){
//Unlocked sets
int nbunlocked = 0;
for (int i = 0; i < MtgSets::SetsList->nb_items; i++){
string s = MtgSets::SetsList->values[i];
sprintf(buffer,"unlocked_%s", s.c_str());
if (1 == options[buffer].number) nbunlocked++;
if (1 == options[Options::optionSet(i)].number) nbunlocked++;
}
sprintf(buff2, _("You have unlocked %i expansions out of %i").c_str(),nbunlocked, MtgSets::SetsList->nb_items);
scroller->Add(buff2);

View File

@@ -48,7 +48,7 @@ void GameStateOptions::Start()
optionsTabs->Add(optionsList);
optionsList = NEW OptionsList("Profiles");
OptionNewProfile * key = NEW OptionNewProfile("","New Profile");
OptionNewProfile * key = NEW OptionNewProfile("New Profile");
key->bShowValue = false;
optionsList->Add(key);
OptionProfile * pickProf = NEW OptionProfile(mParent);

View File

@@ -71,18 +71,14 @@ void GameStateShop::load(){
for (int i = 0; i < MtgSets::SetsList->nb_items; i++){
string s = MtgSets::SetsList->values[i];
if (s.compare("10E") == 0) defaultSet = i;
char buffer[4096];
sprintf(buffer,"unlocked_%s", s.c_str());
unlocked[i] = options[buffer].number;
unlocked[i] = options[Options::optionSet(i)].number;
if (unlocked[i])
ok = 1;
}
if (!ok){
unlocked[defaultSet] = 1;
string s = MtgSets::SetsList->values[defaultSet];
char buffer[4096];
sprintf(buffer,"unlocked_%s", s.c_str());
options[buffer] = GameOption(1);
options[Options::optionSet(defaultSet)] = GameOption(1);
options.save();
}

View File

@@ -1,8 +1,6 @@
#include "../include/config.h"
#include "../include/OptionItem.h"
#include "../include/GameApp.h"
#include <JGE.h>
#include "../include/GameOptions.h"
#include "../include/PlayerData.h"
#include "../include/Translate.h"
#include <dirent.h>
@@ -34,7 +32,7 @@ return out << "OptionItem ::: displayValue : " << displayValue
<< " ; x,y : " << x << "," << y;
}
OptionItem::OptionItem( string _id, string _displayValue) {
OptionItem::OptionItem( int _id, string _displayValue) {
id = _id;
displayValue = _(_displayValue);
canSelect=true;
@@ -72,7 +70,7 @@ void OptionInteger::Render(){
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;
strDefault = _sDef;
maxValue = _maxValue;
@@ -84,7 +82,7 @@ OptionInteger::OptionInteger(string _id, string _displayValue, int _maxValue, in
}
void OptionInteger::setData(){
if(id != "")
if(id != INVALID_OPTION)
options[id] = GameOption(value);
}
@@ -130,7 +128,8 @@ void OptionSelect::Render(){
void OptionSelect::setData()
{
if(id == "") return;
if(id == INVALID_OPTION) return;
if (value < selections.size())
options[id] = GameOption(selections[value]);
}
@@ -356,7 +355,7 @@ void OptionDirectory::Reload(){
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;
struct dirent *mDit;
char buf[4096];
@@ -741,8 +740,8 @@ void OptionString::Render(){
}
void OptionString::setData(){
if(id != "")
options[id] = GameOption(value);
if(id != INVALID_OPTION)
options[id] = GameOption(value);
}
void OptionString::updateValue(){
options.keypadStart(value,&value);
@@ -780,10 +779,10 @@ int OptionNewProfile::Submode(){
return OPTIONS_SUBMODE_NORMAL;
}
OptionString::OptionString(string _id, string _displayValue): OptionItem(_id, _displayValue)
OptionString::OptionString(int _id, string _displayValue): OptionItem(_id, _displayValue)
{
bShowValue=true;
if(_id != "")
if(id != INVALID_OPTION)
value=options[_id].str;
}
@@ -810,23 +809,31 @@ void OptionVolume::updateValue(){
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;
}
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()
{
EnumDefinition * def = ourDefined();
if(!def)
return;
++index;
if (index >= values.size()) index = 0;
if (index >= def->values.size()) index = 0;
}
void OptionEnum::Render()
{
EnumDefinition * def = ourDefined();
JLBFont * mFont = resources.GetJLBFont("f3");
if (hasFocus)
mFont->SetColor(options[Metrics::OPTION_ITEM_TCH].asColor(ARGB(255,255,255,0)));
@@ -835,34 +842,66 @@ void OptionEnum::Render()
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)));
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()
{
for (vector<assoc>::iterator it = values.begin(); it != values.end(); ++it)
if (it->second == options[id].str)
{
index = it - values.begin();
return;
}
index = 0;
EnumDefinition * def = ourDefined();
if(def != NULL)
index = def->findIndex(options[id].number);
}
EnumDefinition * OptionEnum::getDefinition(){
return NULL;
}
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"));
values.push_back(assoc(VISIBLE, "visible"));
getDefinition();
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"));
values.push_back(assoc(HORIZONTAL, "horizontal"));
getDefinition();
Reload();
};