Files
commandergenius/project/jni/application/enigma/src/options.cpp
2010-10-13 17:30:44 +03:00

291 lines
7.1 KiB
C++
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Copyright (C) 2002,2003,2005 Daniel Heck
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include "errors.hh"
#include "lua.hh"
#include "main.hh"
#include "options.hh"
#include "PreferenceManager.hh"
#include "sound.hh"
#include "ecl_system.hh"
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <set>
#ifndef CXXLUA
extern "C" {
#include <lua.h>
#include <lauxlib.h>
}
#else
#include <lua.h>
#include <lauxlib.h>
#endif
#ifdef __MINGW32__
# include <windows.h>
#endif
using namespace enigma;
/* -------------------- LevelStatus implementation -------------------- */
namespace enigma_options
{
LevelStatus::LevelStatus(int easy, int hard, int finished_, int solved_rev)
: time_easy (easy),
time_hard (hard),
finished (finished_),
solved_revision (solved_rev) {
}
bool LevelStatus::operator == (const LevelStatus& other) const {
return (time_easy == other.time_easy &&
time_hard == other.time_hard &&
finished == other.finished &&
solved_revision == other.solved_revision);
}
}
/* -------------------- Variables -------------------- */
namespace enigma_options
{
bool LevelStatusChanged = false;
// bool MustRestart = false;
// bool MustRestartLevel = false;
}
/* -------------------- Functions -------------------- */
bool options::HasOption (const char *name, std::string &value) {
bool hasOption;
const char * result;
lua_State *L = lua::GlobalState();
lua_getglobal (L, "options");
lua_pushstring (L, name);
lua_rawget (L, -2);
result = lua_tostring (L, -1);
if (result != NULL) {
hasOption = true;
value = result;
} else {
hasOption = false;
}
lua_pop (L, 2);
return hasOption;
}
void options::SetOption (const char *name, double value)
{
app.prefs->setProperty(name, value);
}
void options::SetOption (const char *name, const std::string &value)
{
app.prefs->setProperty(name, value);
}
void options::GetOption (const char *name, double &value)
{
app.prefs->getProperty(name, value);
}
void options::GetOption (const char *name, std::string &value) {
app.prefs->getProperty(name, value);
}
bool options::GetBool (const char *name) {
double val = 0;
GetOption (name, val);
return val != 0;
}
double options::GetDouble (const char *name) {
double val = 0;
GetOption (name, val);
return val;
}
int options::GetInt (const char *name) {
double val = 0;
GetOption (name, val);
return static_cast<int>(val);
}
double options::SetMouseSpeed (double speed)
{
double oldspeed = GetMouseSpeed();
double newspeed = ecl::Clamp<double>(speed, MIN_MouseSpeed, MAX_MouseSpeed);
SetOption("MouseSpeed", newspeed);
return oldspeed;
}
double options::GetMouseSpeed ()
{
return GetDouble ("MouseSpeed");
}
void options::UpdateVolume()
{
sound::SetSoundVolume (GetDouble("SoundVolume"));
sound::SetMusicVolume (GetDouble("MusicVolume"));
}
std::string options::GetString (const char *name)
{
std::string val;
GetOption (name, val);
return val;
}
static void UpdateLevelStatus(const std::string &levelname,
const options::LevelStatus &stat)
{
lua_State *L = lua::GlobalState();
int oldtop = lua_gettop(L);
lua_getglobal(L, "stats");
lua_pushstring (L, levelname.c_str());
lua_newtable (L);
lua_pushnumber (L, stat.time_easy); lua_rawseti (L, -2, 1);
lua_pushnumber (L, stat.time_hard); lua_rawseti (L, -2, 2);
lua_pushnumber (L, stat.finished); lua_rawseti (L, -2, 3);
lua_pushnumber (L, stat.solved_revision); lua_rawseti (L, -2, 4);
lua_rawset (L, -3); // stats[levename] =
lua_settop(L, oldtop);
}
bool options::GetLevelStatus (const std::string &levelname,
LevelStatus &stat)
{
lua_State *L = lua::GlobalState();
int oldtop = lua_gettop(L);
lua_getglobal(L, "stats");
lua_pushstring (L, levelname.c_str());
lua_rawget (L, -2);
if (!lua_istable(L, -1) || luaL_getn(L, -1)!=4) {
lua_settop(L, oldtop);
return false;
}
lua_rawgeti (L, -1, 1); stat.time_easy = (int) lua_tonumber (L, -1); lua_pop(L, 1);
lua_rawgeti (L, -1, 2); stat.time_hard = (int) lua_tonumber (L, -1); lua_pop(L, 1);
lua_rawgeti (L, -1, 3); stat.finished = (int) lua_tonumber (L, -1); lua_pop(L, 1);
lua_rawgeti (L, -1, 4); stat.solved_revision = (int) lua_tonumber (L, -1);
lua_settop(L, oldtop);
if (stat.solved_revision == 0 && stat.finished>0) {
// revision 0 is an error (lowest allowed revision number is 1)
printf("Auto-increasing revision number of '%s'\n", levelname.c_str());
stat.solved_revision = 1;
UpdateLevelStatus(levelname, stat); // update this correction
}
return true;
}
/* Determine name of the user's personal configuration file. */
static std::string
Personal_ConfigurationFileName()
{
std::string fname = "enigmarc.lua";
if (getenv ("HOME") != 0)
fname = ecl::ExpandPath ("~/.enigmarc");
return fname;
}
static std::string
System_ConfigurationFileName()
{
return app.systemFS->findFile ("enigma_conf.lua");
}
#ifdef __MINGW32__
static std::string
Windows_ConfigurationFileName()
{
std::string result = ecl::ApplicationDataPath();
if (!result.empty())
return result + "/enigmarc.lua";
else
return Personal_ConfigurationFileName();
}
#endif
static bool
load_from_file (const std::string &fname)
{
lua::Error errcode = lua::DoAbsoluteFile(lua::GlobalState(), fname.c_str());
bool success = (errcode == 0 || errcode == lua::ERRFILE);
if (!success) {
enigma::Log << "error in file `" << fname <<"'\n";
}
return success;
}
static bool
load_options (const std::string &fname)
{
bool success1 = load_from_file (fname);
bool success2 = load_from_file (fname + "2");
return success1 && success2;
}
bool options::Load ()
{
std::string fname;
bool success = true;
fname = System_ConfigurationFileName();
success &= load_options (fname);
#ifdef __MINGW32__
fname = Windows_ConfigurationFileName();
success &= load_options (fname);
#endif
// personal config (in $HOME or current directory) overides all!
fname = Personal_ConfigurationFileName();
success &= load_options (fname);
LevelStatusChanged = false;
return success;
}