~ubuntu-branches/ubuntu/hoary/enigma/hoary

« back to all changes in this revision

Viewing changes to src/options.cc

  • Committer: Bazaar Package Importer
  • Author(s): Erich Schubert
  • Date: 2004-04-09 23:55:15 UTC
  • Revision ID: james.westby@ubuntu.com-20040409235515-ld1mi1mkmkse35hs
Tags: upstream-0.81.1
ImportĀ upstreamĀ versionĀ 0.81.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2002,2003 Daniel Heck
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License
 
6
 * as published by the Free Software Foundation; either version 2
 
7
 * of the License, or (at your option) any later version.
 
8
 *
 
9
 * This program is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
 * GNU General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU General Public License along
 
15
 * with this program; if not, write to the Free Software Foundation, Inc.,
 
16
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
 
17
 *
 
18
 * $Id: options.cc,v 1.22.2.2 2003/09/28 20:41:54 dheck Exp $
 
19
 */
 
20
#include "enigma.hh"
 
21
#ifdef __MINGW32__
 
22
    #include <windows.h>
 
23
#endif
 
24
#include "lua.hh"
 
25
#include "options.hh"
 
26
#include "system.hh"
 
27
#include "game.hh"
 
28
#include "px/dict.hh"
 
29
 
 
30
#include <cassert>
 
31
#include <cstdio>
 
32
#include <cstdlib>
 
33
#include <string>
 
34
 
 
35
using namespace options;
 
36
using namespace std;
 
37
 
 
38
namespace options
 
39
{
 
40
    int    BitsPerPixel      = 16;
 
41
    double MouseSpeed        = 5.0;
 
42
    double MouseDamping      = 25.0;
 
43
    bool   WizardMode        = false;
 
44
    bool   FullScreen        = true;
 
45
    bool   ShowFPS           = false;
 
46
    bool   UseAlpha          = true;
 
47
    bool   Nograb            = false;
 
48
    bool   Nozoom            = true;
 
49
    bool   InGameMusic       = false;
 
50
    int    Difficulty        = enigma::DIFFICULTY_HARD ;
 
51
    int    VideoMode         = 0;
 
52
    int    LevelMenuPosition = 0;
 
53
 
 
54
    double SoundVolume      = 1.0;
 
55
    double MusicVolume      = 1.0;
 
56
    double StereoSeparation = 10.0;
 
57
 
 
58
    string MenuMusicFile  = "/sound/menu.s3m";
 
59
    string LevelMusicFile = "/sound/Emilie.xm";
 
60
 
 
61
    int SoundSet = 0;
 
62
    // 0   = 'enigma' for enigma, appropriate oxyd sound sets for diff. oxyd versions
 
63
    // 1   = 'enigma'
 
64
    // 2.. = OxydVersion-2
 
65
 
 
66
    bool SkipSolvedLevels = false;
 
67
 
 
68
    // not stored in ~/.enigmarc :
 
69
 
 
70
    bool LevelStatusChanged = false;
 
71
    bool MustRestart        = false;
 
72
    bool MustRestartLevel   = false;
 
73
}
 
74
 
 
75
namespace
 
76
{
 
77
    px::Dict<LevelStatus> level_status_dict;
 
78
}
 
79
 
 
80
 
 
81
LevelStatus::LevelStatus(int easy, int hard, int fin, time_t solv)
 
82
: par_easy(easy),
 
83
  par_hard(hard),
 
84
  finished(fin),
 
85
  solved_at(solv)
 
86
{
 
87
    if (!solved_at && fin>0)
 
88
        solved_at = time(0); // default to now
 
89
}
 
90
 
 
91
bool LevelStatus::operator != (const LevelStatus& other) const
 
92
{
 
93
    return !(par_easy == other.par_easy &&
 
94
             par_hard == other.par_hard &&
 
95
             finished == other.finished &&
 
96
             solved_at == other.solved_at);
 
97
}
 
98
 
 
99
 
 
100
static string
 
101
levelkey(const string &/*levelpack*/, const string &levelname)
 
102
{
 
103
    return string("#")+levelname;
 
104
}
 
105
 
 
106
/* Get the status of a particular level in a particular pack.
 
107
   Returns 0 if no record for this level exists. */
 
108
LevelStatus *
 
109
options::GetLevelStatus(const string &levelpack, const string &levelname)
 
110
{
 
111
    px::Dict<LevelStatus>::iterator i;
 
112
    i = level_status_dict.find (levelkey (levelpack, levelname));
 
113
    return (i != level_status_dict.end()) ? &i->second : 0;
 
114
}
 
115
 
 
116
/* Set the status of a particular level.  The previous entry (if
 
117
   available) for this level is discarded. */
 
118
void
 
119
options::SetLevelStatus(const string &levelpack, const string &levelname,
 
120
                        const LevelStatus &stat)
 
121
{
 
122
    string                          key = levelkey (levelpack, levelname);
 
123
    px::Dict<LevelStatus>::iterator i   = level_status_dict.find (key);
 
124
 
 
125
    if (i != level_status_dict.end()) { // status exists -> overwrite
 
126
        if (i->second != stat) {
 
127
            LevelStatusChanged = true;
 
128
        }
 
129
        i->second = stat;
 
130
    }
 
131
    else {
 
132
        level_status_dict.insert(key,stat);
 
133
        LevelStatusChanged = true;
 
134
    }
 
135
}
 
136
 
 
137
bool
 
138
options::SetLevelTime(const string &pack, const string &level, int difficulty, int time)
 
139
{
 
140
    SetLevelFinished(pack, level, difficulty);
 
141
    LevelStatus *stat = GetLevelStatus(pack, level);
 
142
 
 
143
    assert(stat);
 
144
 
 
145
    bool new_record = false;
 
146
 
 
147
    if (difficulty == enigma::DIFFICULTY_EASY) {
 
148
        if (stat->par_easy > time || stat->par_easy == -1) {
 
149
            stat->par_easy     = time;
 
150
            LevelStatusChanged = true;
 
151
            new_record = true;
 
152
        }
 
153
    }
 
154
    else if (difficulty == enigma::DIFFICULTY_HARD) {
 
155
        if (stat->par_hard > time || stat->par_hard == -1) {
 
156
            stat->par_hard     = time;
 
157
            LevelStatusChanged = true;
 
158
            new_record = true;
 
159
        }
 
160
    }
 
161
    return new_record;
 
162
}
 
163
 
 
164
void
 
165
options::SetLevelFinished(const string &pack, const string &level, int difficulty)
 
166
{
 
167
    assert(difficulty==enigma::DIFFICULTY_EASY || difficulty==enigma::DIFFICULTY_HARD);
 
168
 
 
169
    if (LevelStatus *stat = GetLevelStatus(pack, level)) {
 
170
        stat->finished  |= difficulty;
 
171
        stat->solved_at  = time(0);
 
172
    }
 
173
    else {
 
174
        SetLevelStatus(pack, level, LevelStatus(-1, -1, difficulty));
 
175
    }
 
176
 
 
177
    LevelStatusChanged = true;
 
178
}
 
179
 
 
180
/* Determine name of the user's personal configuration file. */
 
181
static string
 
182
Personal_ConfigurationFileName()
 
183
{
 
184
    string fname = "enigmarc.lua";
 
185
 
 
186
    if (getenv ("HOME") != 0)
 
187
        fname = sysdep::expand_path ("~/.enigmarc");
 
188
 
 
189
    return fname;
 
190
}
 
191
 
 
192
static string
 
193
System_ConfigurationFileName()
 
194
{
 
195
    return enigma::FindDataFile ("enigma_conf.lua");
 
196
}
 
197
 
 
198
#ifdef __MINGW32__
 
199
 
 
200
static string
 
201
Windows_ConfigurationFileName()
 
202
{
 
203
    typedef HRESULT (WINAPI *SHGETFOLDERPATH)( HWND, int, HANDLE, DWORD, LPTSTR );
 
204
#   define CSIDL_FLAG_CREATE 0x8000
 
205
#   define CSIDL_APPDATA 0x1A
 
206
#   define SHGFP_TYPE_CURRENT 0
 
207
 
 
208
    HINSTANCE shfolder_dll;
 
209
    SHGETFOLDERPATH SHGetFolderPath ;
 
210
 
 
211
    /* load the shfolder.dll to retreive SHGetFolderPath */
 
212
    if( ( shfolder_dll = LoadLibrary("shfolder.dll") ) != NULL )
 
213
    {
 
214
        SHGetFolderPath = (SHGETFOLDERPATH)GetProcAddress( shfolder_dll, "SHGetFolderPathA");
 
215
        if ( SHGetFolderPath != NULL )
 
216
        {
 
217
            TCHAR szPath[MAX_PATH] = "";
 
218
 
 
219
            /* get the "Application Data" folder for the current user */
 
220
            if( S_OK == SHGetFolderPath( NULL, CSIDL_APPDATA | CSIDL_FLAG_CREATE,
 
221
                                         NULL, SHGFP_TYPE_CURRENT, szPath) )
 
222
            {
 
223
                FreeLibrary( shfolder_dll);
 
224
                return string(szPath) + "/enigmarc.lua";
 
225
            }
 
226
        }
 
227
        FreeLibrary( shfolder_dll);
 
228
    }
 
229
 
 
230
    return Personal_ConfigurationFileName();
 
231
}
 
232
 
 
233
#endif
 
234
 
 
235
 
 
236
bool
 
237
options::Save ()
 
238
{
 
239
#ifdef __MINGW32__
 
240
    string fname = Windows_ConfigurationFileName();
 
241
#else
 
242
    string fname = Personal_ConfigurationFileName();
 
243
#endif
 
244
    FILE *fp = fopen(fname.c_str(), "wt");
 
245
 
 
246
    if (fp) {
 
247
        fprintf (fp, "options.MouseSpeed = %f\n",           MouseSpeed);
 
248
        fprintf (fp, "options.MouseDamping = %f\n",         MouseDamping);
 
249
        fprintf (fp, "options.FullScreen = %d\n",           FullScreen);
 
250
        fprintf (fp, "options.UseAlpha = %d\n",             UseAlpha);
 
251
        fprintf (fp, "options.SoundVolume = %f\n",          SoundVolume);
 
252
        fprintf (fp, "options.MusicVolume = %f\n",          MusicVolume);
 
253
        fprintf (fp, "options.InGameMusic = %d\n",          InGameMusic);
 
254
        fprintf (fp, "options.StereoSeparation = %f\n",     StereoSeparation);
 
255
        fprintf (fp, "options.MenuMusicFile = \"%s\"\n",    MenuMusicFile.c_str());
 
256
        fprintf (fp, "options.LevelMusicFile = \"%s\"\n",   LevelMusicFile.c_str());
 
257
        fprintf (fp, "options.SoundSet = \"%i\"\n",         SoundSet);
 
258
        fprintf (fp, "options.SkipSolvedLevels = %d\n",     SkipSolvedLevels);
 
259
        fprintf (fp, "options.Difficulty = %d\n",           Difficulty);
 
260
        fprintf (fp, "options.VideoMode = %d\n",            VideoMode);
 
261
        fprintf (fp, "options.LevelMenuPosition = %d\n",    LevelMenuPosition);
 
262
 
 
263
        // Save level information
 
264
        px::Dict<LevelStatus>::iterator i=level_status_dict.begin();
 
265
        for (; i!=level_status_dict.end(); ++i) {
 
266
            LevelStatus& ls = i->second;
 
267
 
 
268
            fprintf (fp, "options.LevelStat(\"%s\", {%d, %d, %d, %ld})\n",
 
269
                     i->first.c_str(),
 
270
                     ls.par_easy,
 
271
                     ls.par_hard,
 
272
                     ls.finished,
 
273
                     ls.solved_at);
 
274
        }
 
275
 
 
276
        fclose(fp);
 
277
 
 
278
        LevelStatusChanged = false;
 
279
        return true;
 
280
    }
 
281
    return false;
 
282
}
 
283
 
 
284
static bool
 
285
load_from_file (const char *fname)
 
286
{
 
287
    switch (lua_dofile (lua::state, fname)) {
 
288
    case 0:                     // Everything ok
 
289
    case LUA_ERRFILE:           // File not found is not fatal
 
290
        return true;
 
291
    default:
 
292
        return false;           // All other errors are
 
293
    }
 
294
}
 
295
 
 
296
bool
 
297
options::Load ()
 
298
{
 
299
    string fname;
 
300
    bool error = false;
 
301
 
 
302
    fname = System_ConfigurationFileName();
 
303
    error |= load_from_file (fname.c_str());
 
304
 
 
305
    fname = Personal_ConfigurationFileName();
 
306
    error |= load_from_file (fname.c_str());
 
307
 
 
308
#ifdef __MINGW32__
 
309
    fname  = Windows_ConfigurationFileName();
 
310
    error |= load_from_file (fname.c_str());
 
311
#endif
 
312
 
 
313
    LevelStatusChanged = false;
 
314
 
 
315
    return error;
 
316
}
 
317