Implemented autosave (#292)

dev-mp
krzys-h 2014-11-11 14:50:44 +01:00
parent b8103963c3
commit a1fe9c8d7f
9 changed files with 366 additions and 39 deletions

View File

@ -241,6 +241,9 @@ enum EventType
EVENT_INTERFACE_EDITVALUE= 477, EVENT_INTERFACE_EDITVALUE= 477,
EVENT_INTERFACE_SOLUCE4 = 478, EVENT_INTERFACE_SOLUCE4 = 478,
EVENT_INTERFACE_BLOOD = 479, EVENT_INTERFACE_BLOOD = 479,
EVENT_INTERFACE_AUTOSAVE_ENABLE = 780,
EVENT_INTERFACE_AUTOSAVE_INTERVAL = 781,
EVENT_INTERFACE_AUTOSAVE_SLOTS = 782,
EVENT_INTERFACE_KINFO1 = 500, EVENT_INTERFACE_KINFO1 = 500,
EVENT_INTERFACE_KINFO2 = 501, EVENT_INTERFACE_KINFO2 = 501,

View File

@ -154,47 +154,66 @@ CSNDFile* CResourceManager::GetSNDFileHandler(const std::string &filename)
bool CResourceManager::Exists(const std::string &filename) bool CResourceManager::Exists(const std::string &filename)
{ {
return PHYSFS_exists(CleanPath(filename).c_str()); if(PHYSFS_isInit())
{
return PHYSFS_exists(CleanPath(filename).c_str());
}
return false;
} }
bool CResourceManager::DirectoryExists(const std::string& directory) bool CResourceManager::DirectoryExists(const std::string& directory)
{ {
return PHYSFS_exists(CleanPath(directory).c_str()) && PHYSFS_isDirectory(CleanPath(directory).c_str()); if(PHYSFS_isInit())
{
return PHYSFS_exists(CleanPath(directory).c_str()) && PHYSFS_isDirectory(CleanPath(directory).c_str());
}
return false;
} }
bool CResourceManager::CreateDirectory(const std::string& directory) bool CResourceManager::CreateDirectory(const std::string& directory)
{ {
return PHYSFS_mkdir(CleanPath(directory).c_str()); if(PHYSFS_isInit())
{
return PHYSFS_mkdir(CleanPath(directory).c_str());
}
return false;
} }
//TODO: Don't use boost::filesystem here //TODO: Don't use boost::filesystem here
bool CResourceManager::RemoveDirectory(const std::string& directory) bool CResourceManager::RemoveDirectory(const std::string& directory)
{ {
bool success = true; if(PHYSFS_isInit())
std::string writeDir = PHYSFS_getWriteDir();
try
{ {
fs::remove_all(writeDir + "/" + CleanPath(directory)); bool success = true;
std::string writeDir = PHYSFS_getWriteDir();
try
{
fs::remove_all(writeDir + "/" + CleanPath(directory));
}
catch (std::exception & e)
{
success = false;
}
return success;
} }
catch (std::exception & e) return false;
{
success = false;
}
return success;
} }
std::vector<std::string> CResourceManager::ListFiles(const std::string &directory) std::vector<std::string> CResourceManager::ListFiles(const std::string &directory)
{ {
std::vector<std::string> result; std::vector<std::string> result;
char **files = PHYSFS_enumerateFiles(CleanPath(directory).c_str()); if(PHYSFS_isInit())
for (char **i = files; *i != nullptr; i++)
{ {
result.push_back(*i); char **files = PHYSFS_enumerateFiles(CleanPath(directory).c_str());
}
PHYSFS_freeList(files); for (char **i = files; *i != nullptr; i++)
{
result.push_back(*i);
}
PHYSFS_freeList(files);
}
return result; return result;
} }
@ -203,18 +222,21 @@ std::vector<std::string> CResourceManager::ListDirectories(const std::string &di
{ {
std::vector<std::string> result; std::vector<std::string> result;
char **files = PHYSFS_enumerateFiles(CleanPath(directory).c_str()); if(PHYSFS_isInit())
for (char **i = files; *i != nullptr; i++)
{ {
std::string path = CleanPath(directory) + "/" + (*i); char **files = PHYSFS_enumerateFiles(CleanPath(directory).c_str());
if (PHYSFS_isDirectory(path.c_str()))
{
result.push_back(*i);
}
}
PHYSFS_freeList(files); for (char **i = files; *i != nullptr; i++)
{
std::string path = CleanPath(directory) + "/" + (*i);
if (PHYSFS_isDirectory(path.c_str()))
{
result.push_back(*i);
}
}
PHYSFS_freeList(files);
}
return result; return result;
} }
@ -241,6 +263,45 @@ long long CResourceManager::GetLastModificationTime(const std::string& filename)
return -1; return -1;
} }
//TODO: Don't use boost::filesystem. Why doesn't PHYSFS have this?
bool CResourceManager::Move(const std::string& from, const std::string& to)
{
if(PHYSFS_isInit())
{
bool success = true;
std::string writeDir = PHYSFS_getWriteDir();
try
{
fs::rename(writeDir + "/" + CleanPath(from), writeDir + "/" + CleanPath(to));
}
catch (std::exception & e)
{
success = false;
}
return success;
}
return false;
}
//TODO: Don't use boost::filesystem. Why doesn't PHYSFS have this?
bool CResourceManager::Copy(const std::string& from, const std::string& to)
{
if(PHYSFS_isInit())
{
bool success = true;
std::string writeDir = PHYSFS_getWriteDir();
try
{
fs::copy(writeDir + "/" + CleanPath(from), writeDir + "/" + CleanPath(to));
}
catch (std::exception & e)
{
success = false;
}
return success;
}
return false;
}
int CResourceManager::SDLClose(SDL_RWops *context) int CResourceManager::SDLClose(SDL_RWops *context)
{ {

View File

@ -62,6 +62,11 @@ public:
static long long GetFileSize(const std::string &filename); static long long GetFileSize(const std::string &filename);
//! Returns last modification date as timestamp //! Returns last modification date as timestamp
static long long GetLastModificationTime(const std::string &filename); static long long GetLastModificationTime(const std::string &filename);
//! Move file/directory
static bool Move(const std::string &from, const std::string &to);
//! Copy file/directory
static bool Copy(const std::string &from, const std::string &to);
private: private:
static int SDLSeek(SDL_RWops *context, int offset, int whence); static int SDLSeek(SDL_RWops *context, int offset, int whence);

View File

@ -206,6 +206,9 @@ void InitializeRestext()
stringsEvent[EVENT_INTERFACE_EDITVALUE] = TR("Big indent\\Indent 2 or 4 spaces per level defined by braces"); stringsEvent[EVENT_INTERFACE_EDITVALUE] = TR("Big indent\\Indent 2 or 4 spaces per level defined by braces");
stringsEvent[EVENT_INTERFACE_SOLUCE4] = TR("Access to solutions\\Show program \"4: Solution\" in the exercises"); stringsEvent[EVENT_INTERFACE_SOLUCE4] = TR("Access to solutions\\Show program \"4: Solution\" in the exercises");
stringsEvent[EVENT_INTERFACE_BLOOD] = TR("Blood\\Display blood when the astronaut or the alien queen is hit"); stringsEvent[EVENT_INTERFACE_BLOOD] = TR("Blood\\Display blood when the astronaut or the alien queen is hit");
stringsEvent[EVENT_INTERFACE_AUTOSAVE_ENABLE] = TR("Autosave\\Enables autosave");
stringsEvent[EVENT_INTERFACE_AUTOSAVE_INTERVAL] = TR("Autosave interval\\How often your game will autosave");
stringsEvent[EVENT_INTERFACE_AUTOSAVE_SLOTS] = TR("Autosave slots\\How many autosave slots you'll have");
stringsEvent[EVENT_INTERFACE_KDEF] = TR("Standard controls\\Standard key functions"); stringsEvent[EVENT_INTERFACE_KDEF] = TR("Standard controls\\Standard key functions");
stringsEvent[EVENT_INTERFACE_KLEFT] = TR("Turn left\\turns the bot to the left"); stringsEvent[EVENT_INTERFACE_KLEFT] = TR("Turn left\\turns the bot to the left");

View File

@ -708,6 +708,11 @@ CRobotMain::CRobotMain(CApplication* app, bool loadProfile)
m_winTerminate = false; m_winTerminate = false;
m_exitAfterMission = false; m_exitAfterMission = false;
m_autosave = true;
m_autosaveInterval = 15;
m_autosaveSlots = 3;
m_autosaveLast = 0.0f;
m_joystickDeadzone = 0.2f; m_joystickDeadzone = 0.2f;
SetDefaultInputBindings(); SetDefaultInputBindings();
@ -3393,7 +3398,7 @@ void CRobotMain::InitEye()
bool CRobotMain::EventFrame(const Event &event) bool CRobotMain::EventFrame(const Event &event)
{ {
m_time += event.rTime; m_time += event.rTime;
if (!m_movieLock) m_gameTime += event.rTime; if (!m_movieLock && m_pause->GetPause() == PAUSE_NONE) m_gameTime += event.rTime;
if (!m_immediatSatCom && !m_beginSatCom && if (!m_immediatSatCom && !m_beginSatCom &&
m_gameTime > 0.1f && m_phase == PHASE_SIMUL) m_gameTime > 0.1f && m_phase == PHASE_SIMUL)
@ -3404,6 +3409,12 @@ bool CRobotMain::EventFrame(const Event &event)
if(!m_movieLock && m_pause->GetPause() == PAUSE_NONE && m_missionTimerStarted) if(!m_movieLock && m_pause->GetPause() == PAUSE_NONE && m_missionTimerStarted)
m_missionTimer += event.rTime; m_missionTimer += event.rTime;
if(m_pause->GetPause() == PAUSE_NONE && m_autosave && m_gameTime >= m_autosaveLast+(m_autosaveInterval*60) && m_phase == PHASE_SIMUL) {
m_autosaveLast = m_gameTime;
Autosave();
}
//CLogger::GetInstancePointer()->Debug("%f %f %d\n", m_gameTime, m_autosaveLast, m_autosaveInterval);
m_water->EventProcess(event); m_water->EventProcess(event);
m_cloud->EventProcess(event); m_cloud->EventProcess(event);
@ -4742,6 +4753,7 @@ void CRobotMain::CreateScene(bool soluce, bool fixScene, bool resetObject)
m_app->ResetKeyStates(); m_app->ResetKeyStates();
m_time = 0.0f; m_time = 0.0f;
m_gameTime = 0.0f; m_gameTime = 0.0f;
m_autosaveLast = 0.0f;
m_infoUsed = 0; m_infoUsed = 0;
m_selectObject = sel; m_selectObject = sel;
@ -6930,3 +6942,121 @@ void CRobotMain::StartMissionTimer()
m_missionTimerStarted = true; m_missionTimerStarted = true;
} }
} }
void CRobotMain::SetAutosave(bool enable)
{
m_autosave = enable;
m_autosaveLast = m_gameTime;
AutosaveRotate(false);
}
bool CRobotMain::GetAutosave()
{
return m_autosave;
}
void CRobotMain::SetAutosaveInterval(int interval)
{
m_autosaveInterval = interval;
m_autosaveLast = m_gameTime;
}
int CRobotMain::GetAutosaveInterval()
{
return m_autosaveInterval;
}
void CRobotMain::SetAutosaveSlots(int slots)
{
m_autosaveSlots = slots;
AutosaveRotate(false);
}
int CRobotMain::GetAutosaveSlots()
{
return m_autosaveSlots;
}
int CRobotMain::AutosaveRotate(bool freeOne)
{
CLogger::GetInstancePointer()->Debug("Rotate autosaves...\n");
// Find autosave dirs
auto saveDirs = CResourceManager::ListDirectories(std::string(GetSavegameDir()) + "/" + GetGamerName());
std::map<int, std::string> autosaveDirs;
for(auto& dir : saveDirs)
{
try
{
const std::string autosavePrefix = "autosave";
if(dir.substr(0, autosavePrefix.length()) == "autosave")
{
int id = boost::lexical_cast<int>(dir.substr(autosavePrefix.length()));
autosaveDirs[id] = std::string(GetSavegameDir()) + "/" + GetGamerName() + "/" + dir;
}
}
catch(...)
{
CLogger::GetInstancePointer()->Debug("bad?\n");
// skip
}
}
if(autosaveDirs.size() == 0) return 1;
// Remove all but last m_autosaveSlots
std::map<int, std::string> autosavesToKeep;
int last_id = autosaveDirs.rbegin()->first;
int count = 0;
int to_keep = m_autosaveSlots-(freeOne ? 1 : 0);
int new_last_id = Math::Min(autosaveDirs.size(), to_keep);
bool rotate = false;
for(int i = last_id; i > 0; i--)
{
if(autosaveDirs.count(i) > 0)
{
count++;
if(count > m_autosaveSlots-(freeOne ? 1 : 0) || !m_autosave)
{
CLogger::GetInstancePointer()->Trace("Remove %s\n", autosaveDirs[i].c_str());
CResourceManager::RemoveDirectory(autosaveDirs[i]);
rotate = true;
}
else
{
CLogger::GetInstancePointer()->Trace("Keep %s\n", autosaveDirs[i].c_str());
autosavesToKeep[new_last_id-count+1] = autosaveDirs[i];
}
}
}
// Rename autosaves that we kept
if(rotate) {
for(auto& save : autosavesToKeep) {
std::string newDir = std::string(GetSavegameDir()) + "/" + GetGamerName() + "/autosave" + boost::lexical_cast<std::string>(save.first);
CLogger::GetInstancePointer()->Trace("Rename %s -> %s\n", save.second.c_str(), newDir.c_str());
CResourceManager::Move(save.second, newDir);
}
}
return rotate ? count : count+1;
}
void CRobotMain::Autosave()
{
int id = AutosaveRotate(true);
CLogger::GetInstancePointer()->Info("Autosave!\n");
std::string dir = std::string(GetSavegameDir()) + "/" + GetGamerName() + "/autosave" + boost::lexical_cast<std::string>(id);
if (!CResourceManager::DirectoryExists(dir))
{
CResourceManager::CreateDirectory(dir);
}
std::string savegameFileName = dir + "/data.sav";
std::string fileCBot = CResourceManager::GetSaveLocation() + "/" + dir + "/cbot.run";
char timestr[100];
TimeToAscii(time(NULL), timestr);
IOWriteScene(savegameFileName.c_str(), fileCBot.c_str(), const_cast<char*>((std::string("[AUTOSAVE] ")+timestr).c_str()));
m_dialog->MakeSaveScreenshot(dir + "/screen.png");
}

View File

@ -396,6 +396,13 @@ public:
std::string& GetUserLevelName(int id); std::string& GetUserLevelName(int id);
void StartMissionTimer(); void StartMissionTimer();
void SetAutosave(bool enable);
bool GetAutosave();
void SetAutosaveInterval(int interval);
int GetAutosaveInterval();
void SetAutosaveSlots(int slots);
int GetAutosaveSlots();
protected: protected:
bool EventFrame(const Event &event); bool EventFrame(const Event &event);
@ -429,6 +436,9 @@ protected:
void ExecuteCmd(char *cmd); void ExecuteCmd(char *cmd);
bool TestGadgetQuantity(int rank); bool TestGadgetQuantity(int rank);
void UpdateSpeedLabel(); void UpdateSpeedLabel();
int AutosaveRotate(bool freeOne);
void Autosave();
protected: protected:
@ -589,5 +599,10 @@ protected:
bool m_missionTimerEnabled; bool m_missionTimerEnabled;
bool m_missionTimerStarted; bool m_missionTimerStarted;
float m_missionTimer; float m_missionTimer;
bool m_autosave;
int m_autosaveInterval;
int m_autosaveSlots;
float m_autosaveLast;
}; };

View File

@ -167,6 +167,7 @@ CMainDialog::CMainDialog()
m_bCameraInvertY = false; m_bCameraInvertY = false;
m_bEffect = true; m_bEffect = true;
m_bBlood = true; m_bBlood = true;
m_bAutosave = true;
m_shotDelay = 0; m_shotDelay = 0;
m_glintMouse = Math::Point(0.0f, 0.0f); m_glintMouse = Math::Point(0.0f, 0.0f);
@ -1239,6 +1240,34 @@ void CMainDialog::ChangePhase(Phase phase)
pos.y -= 0.048f; pos.y -= 0.048f;
pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_BLOOD); pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_BLOOD);
pc->SetState(STATE_SHADOW); pc->SetState(STATE_SHADOW);
pos.y -= 0.048f;
pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_AUTOSAVE_ENABLE);
pc->SetState(STATE_SHADOW);
pos.y -= 0.048f;
pos.y -= ddim.y;
ddim.x = dim.x*2.5f;
psl = pw->CreateSlider(pos, ddim, -1, EVENT_INTERFACE_AUTOSAVE_INTERVAL);
psl->SetState(STATE_SHADOW);
psl->SetLimit(1.0f, 30.0f);
psl->SetArrowStep(1.0f);
pos.y += ddim.y/2;
GetResource(RES_EVENT, EVENT_INTERFACE_AUTOSAVE_INTERVAL, name);
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name);
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
pos.y -= ddim.y/2;
pos.x = ox+sx*3+dim.x*3.5f;
psl = pw->CreateSlider(pos, ddim, -1, EVENT_INTERFACE_AUTOSAVE_SLOTS);
psl->SetState(STATE_SHADOW);
psl->SetLimit(1.0f, 10.0f);
psl->SetArrowStep(1.0f);
pos.y += ddim.y/2;
GetResource(RES_EVENT, EVENT_INTERFACE_AUTOSAVE_SLOTS, name);
pl = pw->CreateLabel(pos, ddim, 0, EVENT_LABEL1, name);
pl->SetTextAlign(Gfx::TEXT_ALIGN_LEFT);
pos.y -= ddim.y/2;
//? pos.y -= 0.048f; //? pos.y -= 0.048f;
//? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_NICERST); //? pc = pw->CreateCheck(pos, ddim, -1, EVENT_INTERFACE_NICERST);
//? pc->SetState(STATE_SHADOW); //? pc->SetState(STATE_SHADOW);
@ -2570,6 +2599,23 @@ bool CMainDialog::EventProcess(const Event &event)
ChangeSetupButtons(); ChangeSetupButtons();
UpdateSetupButtons(); UpdateSetupButtons();
break; break;
case EVENT_INTERFACE_AUTOSAVE_ENABLE:
m_bAutosave = !m_bAutosave;
m_main->SetAutosave(m_bAutosave);
ChangeSetupButtons();
UpdateSetupButtons();
break;
case EVENT_INTERFACE_AUTOSAVE_INTERVAL:
ChangeSetupButtons();
UpdateSetupButtons();
break;
case EVENT_INTERFACE_AUTOSAVE_SLOTS:
ChangeSetupButtons();
UpdateSetupButtons();
break;
default: default:
break; break;
@ -4175,12 +4221,17 @@ bool CMainDialog::IOWriteScene()
std::string fileCBot = CResourceManager::GetSaveLocation() + "/" + dir + "/cbot.run"; std::string fileCBot = CResourceManager::GetSaveLocation() + "/" + dir + "/cbot.run";
m_main->IOWriteScene(savegameFileName.c_str(), fileCBot.c_str(), info); m_main->IOWriteScene(savegameFileName.c_str(), fileCBot.c_str(), info);
m_shotDelay = 3; MakeSaveScreenshot(dir + "/screen.png");
m_shotName = CResourceManager::GetSaveLocation() + "/" + dir + "/screen.png"; //TODO: Use PHYSFS?
return true; return true;
} }
void CMainDialog::MakeSaveScreenshot(const std::string& name)
{
m_shotDelay = 3;
m_shotName = CResourceManager::GetSaveLocation() + "/" + name; //TODO: Use PHYSFS?
}
// Reads the scene. // Reads the scene.
bool CMainDialog::IOReadScene() bool CMainDialog::IOReadScene()
@ -4726,6 +4777,27 @@ void CMainDialog::UpdateSetupButtons()
{ {
pc->SetState(STATE_CHECK, m_bBlood); pc->SetState(STATE_CHECK, m_bBlood);
} }
pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_AUTOSAVE_ENABLE));
if ( pc != 0 )
{
pc->SetState(STATE_CHECK, m_bAutosave);
}
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_AUTOSAVE_INTERVAL));
if ( ps != 0 )
{
ps->SetState(STATE_ENABLE, m_bAutosave);
ps->SetVisibleValue(m_main->GetAutosaveInterval());
}
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_AUTOSAVE_SLOTS));
if ( ps != 0 )
{
ps->SetState(STATE_ENABLE, m_bAutosave);
ps->SetVisibleValue(m_main->GetAutosaveSlots());
}
pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_SHADOW)); pc = static_cast<CCheck*>(pw->SearchControl(EVENT_INTERFACE_SHADOW));
if ( pc != 0 ) if ( pc != 0 )
@ -4891,6 +4963,20 @@ void CMainDialog::ChangeSetupButtons()
value = ps->GetVisibleValue(); value = ps->GetVisibleValue();
m_sound->SetMusicVolume(static_cast<int>(value)); m_sound->SetMusicVolume(static_cast<int>(value));
} }
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_AUTOSAVE_INTERVAL));
if ( ps != 0 )
{
value = ps->GetVisibleValue();
m_main->SetAutosaveInterval(static_cast<int>(value));
}
ps = static_cast<CSlider*>(pw->SearchControl(EVENT_INTERFACE_AUTOSAVE_SLOTS));
if ( ps != 0 )
{
value = ps->GetVisibleValue();
m_main->SetAutosaveSlots(static_cast<int>(value));
}
} }
@ -4913,6 +4999,9 @@ void CMainDialog::SetupMemorize()
GetProfile().SetIntProperty("Setup", "CameraInvertY", m_bCameraInvertY); GetProfile().SetIntProperty("Setup", "CameraInvertY", m_bCameraInvertY);
GetProfile().SetIntProperty("Setup", "InterfaceEffect", m_bEffect); GetProfile().SetIntProperty("Setup", "InterfaceEffect", m_bEffect);
GetProfile().SetIntProperty("Setup", "Blood", m_bBlood); GetProfile().SetIntProperty("Setup", "Blood", m_bBlood);
GetProfile().SetIntProperty("Setup", "Autosave", m_bAutosave);
GetProfile().SetIntProperty("Setup", "AutosaveInterval", m_main->GetAutosaveInterval());
GetProfile().SetIntProperty("Setup", "AutosaveSlots", m_main->GetAutosaveSlots());
GetProfile().SetIntProperty("Setup", "GroundShadow", m_engine->GetShadow()); GetProfile().SetIntProperty("Setup", "GroundShadow", m_engine->GetShadow());
GetProfile().SetIntProperty("Setup", "GroundSpot", m_engine->GetGroundSpot()); GetProfile().SetIntProperty("Setup", "GroundSpot", m_engine->GetGroundSpot());
GetProfile().SetIntProperty("Setup", "ObjectDirty", m_engine->GetDirty()); GetProfile().SetIntProperty("Setup", "ObjectDirty", m_engine->GetDirty());
@ -5066,6 +5155,21 @@ void CMainDialog::SetupRecall()
m_bBlood = iValue; m_bBlood = iValue;
} }
if ( GetProfile().GetIntProperty("Setup", "Autosave", iValue) )
{
m_bAutosave = iValue;
}
if ( GetProfile().GetIntProperty("Setup", "AutosaveInterval", iValue) )
{
m_main->SetAutosaveInterval(iValue);
}
if ( GetProfile().GetIntProperty("Setup", "AutosaveSlots", iValue) )
{
m_main->SetAutosaveSlots(iValue);
}
if ( GetProfile().GetIntProperty("Setup", "GroundShadow", iValue) ) if ( GetProfile().GetIntProperty("Setup", "GroundShadow", iValue) )
{ {
m_engine->SetShadow(iValue); m_engine->SetShadow(iValue);

View File

@ -139,6 +139,8 @@ public:
void ShowSoluceUpdate(); void ShowSoluceUpdate();
std::string& GetUserLevelName(int id); std::string& GetUserLevelName(int id);
void MakeSaveScreenshot(const std::string& name);
protected: protected:
void GlintMove(); void GlintMove();
@ -240,6 +242,7 @@ protected:
bool m_bCameraInvertY; // for CCamera bool m_bCameraInvertY; // for CCamera
bool m_bEffect; // for CCamera bool m_bEffect; // for CCamera
bool m_bBlood; // for CCamera bool m_bBlood; // for CCamera
bool m_bAutosave;
Math::Point m_glintMouse; Math::Point m_glintMouse;
float m_glintTime; float m_glintTime;

View File

@ -469,15 +469,18 @@ void CSlider::Draw()
if ( m_bHoriz ) if ( m_bHoriz )
{ {
sprintf(text, "%d", static_cast<int>(m_min+m_visibleValue*(m_max-m_min))); if ( m_state & STATE_ENABLE )
h = m_engine->GetText()->GetHeight(m_fontType, m_fontSize); {
pos.x = m_pos.x+m_dim.x+(10.0f/640.0f); sprintf(text, "%d", static_cast<int>(m_min+m_visibleValue*(m_max-m_min)));
pos.y = m_pos.y+(m_dim.y-h)/2.0f; h = m_engine->GetText()->GetHeight(m_fontType, m_fontSize);
m_engine->GetText()->DrawText(text, m_fontType, m_fontSize, pos, m_dim.x, Gfx::TEXT_ALIGN_LEFT, 0); pos.x = m_pos.x+m_dim.x+(10.0f/640.0f);
pos.y = m_pos.y+(m_dim.y-h)/2.0f;
m_engine->GetText()->DrawText(text, m_fontType, m_fontSize, pos, m_dim.x, Gfx::TEXT_ALIGN_LEFT, 0);
}
} }
else else
{ {
if ( m_state & STATE_VALUE ) if ( m_state & STATE_VALUE && m_state & STATE_ENABLE )
{ {
pos.x = m_pos.x+m_dim.x+4.0f/640.0f; pos.x = m_pos.x+m_dim.x+4.0f/640.0f;
h = m_dim.y-m_marginButton*2.0f; h = m_dim.y-m_marginButton*2.0f;