~ubuntu-branches/ubuntu/trusty/rlvm/trusty

« back to all changes in this revision

Viewing changes to .pc/002_675426ad62bccf1de10b0ae31dd46331ec47aacb.patch/src/Modules/Module_Sys_Save.cpp

  • Committer: Package Import Robot
  • Author(s): Ying-Chun Liu (PaulLiu)
  • Date: 2013-11-02 02:57:13 UTC
  • mfrom: (10.1.3 sid)
  • Revision ID: package-import@ubuntu.com-20131102025713-yzg31grxr8i7xerh
Tags: 0.13-1
* New upstream release
  - rlvm will now warn on startup when it detects Japanese save data, but
    English patched game files, and offer to reset the save data.
  - Much better support for Little Busters. Most graphical glitches during
    the Little Busters Refrain have been fixed.
  - TCC tone curve effects have been reverse-engineered and implemented
    (thanks to lurkmoar)
  - Sepia scenes (and other graphical filters) should look much better.
  - Simple shake commands implemented (fancy per-layer shaking still
    unimplemented).
  - Make animations smooth: data should be uploaded to the graphics card
    before an animation loop starts, not while the animation loop is
    running.
  - Fixes finding system fonts on Linux
  - Thanks to Elliot Glaysher <glaysher@umich.edu>
* Remove upstreamed patches:
  - debian/patches/002_675426ad62bccf1de10b0ae31dd46331ec47aacb.patch
  - debian/patches/003_5dafabf5448635c4d4526d6e35ea7ec664a27261.patch
  - debian/patches/004_boost-drop-mt.patch
  - debian/patches/005_missing-include.patch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// -*- Mode: C++; tab-width:2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2
 
// vi:tw=80:et:ts=2:sts=2
3
 
//
4
 
// -----------------------------------------------------------------------
5
 
//
6
 
// This file is part of RLVM, a RealLive virtual machine clone.
7
 
//
8
 
// -----------------------------------------------------------------------
9
 
//
10
 
// Copyright (C) 2007 Elliot Glaysher
11
 
//
12
 
// This program is free software; you can redistribute it and/or modify
13
 
// it under the terms of the GNU General Public License as published by
14
 
// the Free Software Foundation; either version 3 of the License, or
15
 
// (at your option) any later version.
16
 
//
17
 
// This program is distributed in the hope that it will be useful,
18
 
// but WITHOUT ANY WARRANTY; without even the implied warranty of
19
 
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 
// GNU General Public License for more details.
21
 
//
22
 
// You should have received a copy of the GNU General Public License
23
 
// along with this program; if not, write to the Free Software
24
 
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
25
 
//
26
 
// -----------------------------------------------------------------------
27
 
 
28
 
#include "Modules/Module_Sys_Save.hpp"
29
 
 
30
 
#include <algorithm>
31
 
#include <boost/algorithm/string/predicate.hpp>
32
 
#include <boost/bind.hpp>
33
 
#include <boost/filesystem/fstream.hpp>
34
 
#include <boost/filesystem/operations.hpp>
35
 
#include <boost/filesystem/path.hpp>
36
 
#include <boost/lexical_cast.hpp>
37
 
#include <boost/shared_ptr.hpp>
38
 
#include <limits>
39
 
#include <string>
40
 
 
41
 
#include "LongOperations/LoadGameLongOperation.hpp"
42
 
#include "MachineBase/GeneralOperations.hpp"
43
 
#include "MachineBase/LongOperation.hpp"
44
 
#include "MachineBase/Memory.hpp"
45
 
#include "MachineBase/RLMachine.hpp"
46
 
#include "MachineBase/RLModule.hpp"
47
 
#include "MachineBase/RLOperation.hpp"
48
 
#include "MachineBase/RLOperation/Argc_T.hpp"
49
 
#include "MachineBase/RLOperation/Complex_T.hpp"
50
 
#include "MachineBase/RLOperation/RLOp_Store.hpp"
51
 
#include "MachineBase/RLOperation/References.hpp"
52
 
#include "MachineBase/RLOperation/Special_T.hpp"
53
 
#include "MachineBase/SaveGameHeader.hpp"
54
 
#include "MachineBase/Serialization.hpp"
55
 
#include "Systems/Base/Colour.hpp"
56
 
#include "Systems/Base/Surface.hpp"
57
 
#include "Systems/Base/System.hpp"
58
 
#include "libReallive/intmemref.h"
59
 
#include "utf8cpp/utf8.h"
60
 
 
61
 
// For copy_n, which isn't part of the C++ standard and doesn't come on
62
 
// OSX.
63
 
#include <boost/multi_array/algorithm.hpp>
64
 
 
65
 
using namespace libReallive;
66
 
using boost::lexical_cast;
67
 
using boost::starts_with;
68
 
using boost::ends_with;
69
 
using boost::bind;
70
 
using boost::shared_ptr;
71
 
namespace fs = boost::filesystem;
72
 
 
73
 
// -----------------------------------------------------------------------
74
 
 
75
 
namespace {
76
 
 
77
 
struct SaveExists : public RLOp_Store_1< IntConstant_T > {
78
 
  int operator()(RLMachine& machine, int slot) {
79
 
    fs::path saveFile = Serialization::buildSaveGameFilename(machine, slot);
80
 
    return fs::exists(saveFile) ? 1 : 0;
81
 
  }
82
 
};
83
 
 
84
 
struct SaveDate
85
 
    : public RLOp_Store_5<IntConstant_T, IntReference_T, IntReference_T,
86
 
                          IntReference_T, IntReference_T> {
87
 
  int operator()(RLMachine& machine, int slot,
88
 
                 IntReferenceIterator yIt, IntReferenceIterator mIt,
89
 
                 IntReferenceIterator dIt, IntReferenceIterator wdIt) {
90
 
    int fileExists = SaveExists()(machine, slot);
91
 
 
92
 
    if (fileExists) {
93
 
      SaveGameHeader header = Serialization::loadHeaderForSlot(machine, slot);
94
 
 
95
 
      *yIt = header.save_time.date().year();
96
 
      *mIt = header.save_time.date().month();
97
 
      *dIt = header.save_time.date().day();
98
 
      *wdIt = header.save_time.date().day_of_week();
99
 
    }
100
 
 
101
 
    return fileExists;
102
 
  }
103
 
};
104
 
 
105
 
struct SaveTime
106
 
    : public RLOp_Store_5<IntConstant_T, IntReference_T, IntReference_T,
107
 
                          IntReference_T, IntReference_T> {
108
 
  int operator()(RLMachine& machine, int slot,
109
 
                 IntReferenceIterator hhIt, IntReferenceIterator mmIt,
110
 
                 IntReferenceIterator ssIt, IntReferenceIterator msIt) {
111
 
    int fileExists = SaveExists()(machine, slot);
112
 
 
113
 
    if (fileExists) {
114
 
      SaveGameHeader header = Serialization::loadHeaderForSlot(machine, slot);
115
 
 
116
 
      *hhIt = header.save_time.time_of_day().hours();
117
 
      *mmIt = header.save_time.time_of_day().minutes();
118
 
      *ssIt = header.save_time.time_of_day().seconds();
119
 
      *msIt = header.save_time.time_of_day().fractional_seconds();
120
 
    }
121
 
 
122
 
    return fileExists;
123
 
  }
124
 
};
125
 
 
126
 
struct SaveDateTime : public RLOp_Store_9<
127
 
  IntConstant_T, IntReference_T, IntReference_T, IntReference_T, IntReference_T,
128
 
  IntReference_T, IntReference_T, IntReference_T, IntReference_T > {
129
 
  int operator()(RLMachine& machine, int slot,
130
 
                 IntReferenceIterator yIt, IntReferenceIterator mIt,
131
 
                 IntReferenceIterator dIt, IntReferenceIterator wdIt,
132
 
                 IntReferenceIterator hhIt, IntReferenceIterator mmIt,
133
 
                 IntReferenceIterator ssIt, IntReferenceIterator msIt) {
134
 
    int fileExists = SaveExists()(machine, slot);
135
 
 
136
 
    if (fileExists) {
137
 
      SaveGameHeader header = Serialization::loadHeaderForSlot(machine, slot);
138
 
 
139
 
      *yIt = header.save_time.date().year();
140
 
      *mIt = header.save_time.date().month();
141
 
      *dIt = header.save_time.date().day();
142
 
      *wdIt = header.save_time.date().day_of_week();
143
 
      *hhIt = header.save_time.time_of_day().hours();
144
 
      *mmIt = header.save_time.time_of_day().minutes();
145
 
      *ssIt = header.save_time.time_of_day().seconds();
146
 
      *msIt = header.save_time.time_of_day().fractional_seconds();
147
 
    }
148
 
 
149
 
    return fileExists;
150
 
  }
151
 
};
152
 
 
153
 
struct SaveInfo
154
 
    : public RLOp_Store_10<IntConstant_T, IntReference_T, IntReference_T,
155
 
                           IntReference_T, IntReference_T, IntReference_T,
156
 
                           IntReference_T, IntReference_T, IntReference_T,
157
 
                           StrReference_T > {
158
 
  int operator()(RLMachine& machine, int slot,
159
 
                 IntReferenceIterator yIt, IntReferenceIterator mIt,
160
 
                 IntReferenceIterator dIt, IntReferenceIterator wdIt,
161
 
                 IntReferenceIterator hhIt, IntReferenceIterator mmIt,
162
 
                 IntReferenceIterator ssIt, IntReferenceIterator msIt,
163
 
                 StringReferenceIterator titleIt) {
164
 
    int fileExists = SaveExists()(machine, slot);
165
 
 
166
 
    if (fileExists) {
167
 
      SaveGameHeader header = Serialization::loadHeaderForSlot(machine, slot);
168
 
 
169
 
      *yIt = header.save_time.date().year();
170
 
      *mIt = header.save_time.date().month();
171
 
      *dIt = header.save_time.date().day();
172
 
      *wdIt = header.save_time.date().day_of_week();
173
 
      *hhIt = header.save_time.time_of_day().hours();
174
 
      *mmIt = header.save_time.time_of_day().minutes();
175
 
      *ssIt = header.save_time.time_of_day().seconds();
176
 
      *msIt = header.save_time.time_of_day().fractional_seconds();
177
 
 
178
 
      // Convert the UTF-8 string to the memory internal CP932
179
 
      *titleIt = header.title;
180
 
    }
181
 
 
182
 
    return fileExists;
183
 
  }
184
 
};
185
 
 
186
 
typedef Argc_T<
187
 
  Special_T<
188
 
    Complex3_T<IntReference_T, IntReference_T, IntConstant_T>,
189
 
    Complex3_T<StrReference_T, StrReference_T, IntConstant_T> > >
190
 
GetSaveFlagList;
191
 
 
192
 
// Retrieves the values of variables from saved games. If slot is
193
 
// empty, returns 0 and does nothing further; if slot contains a saved
194
 
// game, returns 1 and processes the list of structures. For each
195
 
// entry in the list, count values are copied to a block of variables
196
 
// starting with dst, reading from src: the values copied are those
197
 
// that are stored in the saved game in slot.
198
 
//
199
 
// For example, an RPG that stored the player's level in F[100], the
200
 
// player's hit points in F[101], and the name of the player's class
201
 
// in S[10], could retrieve these values from saved games to display
202
 
// them in a custom load menu as follows:
203
 
//
204
 
//   str menu_line[10]
205
 
//   for (int i = 0) (i < length(menu_line)) (i += 1):
206
 
//     int (block) level, hp
207
 
//     str class
208
 
//     GetSaveFlag(i, {intF[100], level, 2}, {strS[10], class, 1})
209
 
//     menu_line[i] = 'Level \i{level} \s{class}, \i{hp} HP';
210
 
struct GetSaveFlag : public RLOp_Store_2<
211
 
  IntConstant_T, GetSaveFlagList> {
212
 
  /// Main operation
213
 
  int operator()(RLMachine& machine, int slot, GetSaveFlagList::type flagList) {
214
 
    int fileExists = SaveExists()(machine, slot);
215
 
    if (!fileExists)
216
 
      return 0;
217
 
 
218
 
    Memory overlayedMemory(machine, slot);
219
 
    Serialization::loadLocalMemoryForSlot(machine, slot, overlayedMemory);
220
 
 
221
 
    using boost::detail::multi_array::copy_n;
222
 
    for (GetSaveFlagList::type::iterator it = flagList.begin();
223
 
         it != flagList.end(); ++it) {
224
 
      switch (it->type) {
225
 
        case 0: {
226
 
          IntReferenceIterator jt = it->first.get<0>()
227
 
                                    .changeMemoryTo(&overlayedMemory);
228
 
          copy_n(jt, it->first.get<2>(), it->first.get<1>());
229
 
          break;
230
 
        }
231
 
        case 1: {
232
 
          StringReferenceIterator jt = it->second.get<0>()
233
 
                                       .changeMemoryTo(&overlayedMemory);
234
 
          copy_n(jt, it->second.get<2>(), it->second.get<1>());
235
 
          break;
236
 
        }
237
 
        default:
238
 
          throw rlvm::Exception("Illegal value in Special_T in GetSaveFlag");
239
 
          break;
240
 
      }
241
 
    }
242
 
 
243
 
    return 1;
244
 
  }
245
 
};
246
 
 
247
 
// Returns the slot most recently saved to, or −1 if no games have
248
 
// been saved.
249
 
struct LatestSave : public RLOp_Store_Void {
250
 
  int operator()(RLMachine& machine) {
251
 
    fs::path saveDir = machine.system().gameSaveDirectory();
252
 
    int latestSlot = -1;
253
 
    time_t latestTime = std::numeric_limits<time_t>::min();
254
 
 
255
 
    if (fs::exists(saveDir)) {
256
 
      fs::directory_iterator end;
257
 
      for (fs::directory_iterator it(saveDir); it != end; ++it) {
258
 
        string filename = it->leaf();
259
 
        if (starts_with(filename, "save") && ends_with(filename, ".sav.gz")) {
260
 
          time_t mtime = fs::last_write_time(*it);
261
 
 
262
 
          if (mtime > latestTime) {
263
 
            latestTime = mtime;
264
 
            latestSlot = lexical_cast<int>(filename.substr(4, 3));
265
 
          }
266
 
        }
267
 
      }
268
 
    }
269
 
 
270
 
    return latestSlot;
271
 
  }
272
 
};
273
 
 
274
 
struct save : public RLOp_Void_1< IntConstant_T > {
275
 
  void operator()(RLMachine& machine, int slot) {
276
 
    Serialization::saveGlobalMemory(machine);
277
 
    Serialization::saveGameForSlot(machine, slot);
278
 
  }
279
 
};
280
 
 
281
 
struct LoadingGameFromSlot : public LoadGameLongOperation {
282
 
  int slot_;
283
 
  explicit LoadingGameFromSlot(RLMachine& machine, int slot)
284
 
      : LoadGameLongOperation(machine), slot_(slot) {}
285
 
 
286
 
  virtual void load(RLMachine& machine) {
287
 
    Serialization::loadGameForSlot(machine, slot_);
288
 
  }
289
 
};
290
 
 
291
 
}  // namespace
292
 
 
293
 
// -----------------------------------------------------------------------
294
 
 
295
 
void Sys_load::operator()(RLMachine& machine, int slot) {
296
 
  // LoadGameLongOperation will add self to |machine|'s stack.
297
 
  new LoadingGameFromSlot(machine, slot);
298
 
}
299
 
 
300
 
// -----------------------------------------------------------------------
301
 
 
302
 
void addSysSaveOpcodes(RLModule& m) {
303
 
  m.addOpcode(1409, 0, "SaveExists", new SaveExists);
304
 
  m.addOpcode(1410, 0, "SaveDate", new SaveDate);
305
 
  m.addOpcode(1411, 0, "SaveTime", new SaveTime);
306
 
  m.addOpcode(1412, 0, "SaveDateTime", new SaveDateTime);
307
 
  m.addOpcode(1413, 0, "SaveInfo", new SaveInfo);
308
 
  m.addOpcode(1414, 0, "GetSaveFlag", new GetSaveFlag);
309
 
  m.addOpcode(1421, 0, "LatestSave", new LatestSave);
310
 
 
311
 
  m.addOpcode(2053, 0, "SetConfirmSaveLoad",
312
 
              callFunction(&System::setConfirmSaveLoad));
313
 
  m.addOpcode(2003, 0, "ConfirmSaveLoad",
314
 
              returnIntValue(&System::confirmSaveLoad));
315
 
 
316
 
  m.addOpcode(3000, 0, "menu_save", new InvokeSyscomAsOp(0));
317
 
  m.addOpcode(3001, 0, "menu_load", new InvokeSyscomAsOp(1));
318
 
 
319
 
  m.addOpcode(3007, 0, "save", new save);
320
 
  m.addOpcode(3107, 0, "save_always", new save);
321
 
 
322
 
  m.addOpcode(3009, 0, "load", new Sys_load);
323
 
  m.addOpcode(3109, 0, "load_always", new Sys_load);
324
 
 
325
 
  m.addOpcode(3100, 0, "menu_save_always", new InvokeSyscomAsOp(0));
326
 
  m.addOpcode(3101, 0, "menu_load_always", new InvokeSyscomAsOp(1));
327
 
 
328
 
  m.addOpcode(3500, 0, "Savepoint",
329
 
              callFunction(&RLMachine::markSavepoint));
330
 
  m.addOpcode(3501, 0, "EnableAutoSavepoints",
331
 
              callFunctionWith(&RLMachine::setMarkSavepoints, 1));
332
 
  m.addOpcode(3502, 0, "DisableAutoSavepoints",
333
 
              callFunctionWith(&RLMachine::setMarkSavepoints, 0));
334
 
}