ScummVM
glk.cpp
Go to the documentation of this file.
1 /* ScummVM - Graphic Adventure Engine
2  *
3  * ScummVM is the legal property of its developers, whose names
4  * are too numerous to list here. Please refer to the COPYRIGHT
5  * file distributed with this source distribution.
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  */
22 
23 #include "common/scummsys.h"
24 #include "common/config-manager.h"
25 #include "common/debug-channels.h"
26 #include "common/events.h"
27 #include "common/file.h"
28 #include "common/language.h"
29 #include "engines/util.h"
30 #include "graphics/scaler.h"
31 #include "graphics/thumbnail.h"
32 #include "glk/glk.h"
33 #include "glk/blorb.h"
34 #include "glk/conf.h"
35 #include "glk/events.h"
36 #include "glk/picture.h"
37 #include "glk/quetzal.h"
38 #include "glk/screen.h"
39 #include "glk/selection.h"
40 #include "glk/sound.h"
41 #include "glk/streams.h"
42 #include "glk/windows.h"
43 
44 namespace Glk {
45 
47 
49  _gameDescription(gameDesc), Engine(syst), _random("Glk"), _quitFlag(false), _blorb(nullptr),
50  _clipboard(nullptr), _conf(nullptr), _debugger(nullptr), _events(nullptr), _pictures(nullptr),
51  _screen(nullptr), _selection(nullptr), _sounds(nullptr), _streams(nullptr), _windows(nullptr),
52  _copySelect(false), _terminated(false), _pcSpeaker(nullptr), _loadSaveSlot(-1),
53  gli_register_obj(nullptr), gli_unregister_obj(nullptr), gli_register_arr(nullptr),
54  gli_unregister_arr(nullptr) {
55  // Set up debug channels
56  DebugMan.addDebugChannel(kDebugCore, "core", "Core engine debug level");
57  DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts");
58  DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling");
59  DebugMan.addDebugChannel(kDebugSound, "sound", "Sound and Music handling");
60 
61  g_vm = this;
62 }
63 
65  delete _blorb;
66  delete _clipboard;
67  delete _conf;
68  delete _debugger;
69  delete _events;
70  delete _pcSpeaker;
71  delete _pictures;
72  delete _screen;
73  delete _selection;
74  delete _sounds;
75  delete _streams;
76  delete _windows;
77 }
78 
81 
82  _conf = new Conf(getInterpreterType());
86  _clipboard = new Clipboard();
87  _events = new Events();
89  _pictures = new Pictures();
90  _selection = new Selection();
91  _sounds = new Sounds();
92  _streams = new Streams();
93  _windows = new Windows(_screen);
94 
95  // Setup mixer
97 }
98 
100  return new Screen();
101 }
102 
104  uint width = ConfMan.hasKey("width") ? ConfMan.getInt("width") : 640;
105  uint height = ConfMan.hasKey("height") ? ConfMan.getInt("height") : 480;
107  Graphics::PixelFormat format = formats.front();
108 
109  for (Common::List<Graphics::PixelFormat>::iterator i = formats.begin(); i != formats.end(); ++i) {
110  if ((*i).bytesPerPixel > 1) {
111  format = *i;
112  break;
113  }
114  }
115 
116  initGraphics(width, height, &format);
117 }
118 
120  // Open up the game file
122  if (!Common::File::exists(filename))
124 
125  if (Blorb::isBlorb(filename)) {
126  // Blorb archive
127  _blorb = new Blorb(filename, getInterpreterType());
128  SearchMan.add("blorb", _blorb, 99, false);
129 
130  if (!_gameFile.open("game", *_blorb))
132  } else {
133  // Check for a secondary blorb file with the same filename
134  Common::StringArray blorbFilenames;
135  Blorb::getBlorbFilenames(filename, blorbFilenames, getInterpreterType(), getGameID());
136 
137  for (uint idx = 0; idx < blorbFilenames.size(); ++idx) {
138  if (Common::File::exists(blorbFilenames[idx])) {
139  _blorb = new Blorb(blorbFilenames[idx], getInterpreterType());
140  SearchMan.add("blorb", _blorb, 99, false);
141  break;
142  }
143  }
144 
145  // Open up the game file
146  if (!_gameFile.open(filename))
148  }
149 
150  // Perform initialization
151  initialize();
152 
153  // Play the game
154  runGame();
155 
156  return Common::kNoError;
157 }
158 
161  filemode_Read, 0);
162  if (ref == nullptr)
163  return Common::kReadingFailed;
164 
165  int slotNumber = ref->_slotNumber;
166  _streams->deleteRef(ref);
167 
168  return loadGameState(slotNumber);
169 }
170 
173  filemode_Write, 0);
174  if (ref == nullptr)
175  return Common::kWritingFailed;
176 
177  int slot = ref->_slotNumber;
179  _streams->deleteRef(ref);
180 
181  return saveGameState(slot, desc);
182 }
183 
186 
188  if (file == nullptr)
189  return Common::kReadingFailed;
190 
192  QuetzalReader r;
193  if (r.open(*file, ID_IFSF)) {
194  // First scan for a SCVM chunk. It has information of the game the save is for,
195  // so if present we can validate the save is for this game
196  for (QuetzalReader::Iterator it = r.begin(); it != r.end(); ++it) {
197  if ((*it)._id == ID_SCVM) {
198  // Skip over date/time & playtime
199  Common::SeekableReadStream *rs = it.getStream();
200  rs->skip(14);
201 
202  uint32 interpType = rs->readUint32BE();
205  delete rs;
206 
207  if (interpType != QuetzalBase::getInterpreterTag(getInterpreterType()) ||
208  parseLanguage(langCode) !=getLanguage() || md5 != getGameMD5())
209  errCode = Common::kReadingFailed;
210  }
211  }
212 
213  if (errCode == Common::kNoError) {
214  // Scan for an uncompressed memory chunk
215  errCode = Common::kReadingFailed; // Presume we won't find chunk
216  for (QuetzalReader::Iterator it = r.begin(); it != r.end(); ++it) {
217  if ((*it)._id == ID_UMem) {
218  Common::SeekableReadStream *rs = it.getStream();
219  errCode = readSaveData(rs).getCode();
220  delete rs;
221  break;
222  }
223  }
224  }
225  }
226 
227  file->close();
228  return errCode;
229 }
230 
232  Common::String msg;
234 
236  if (file == nullptr)
237  return Common::kWritingFailed;
238 
240  QuetzalWriter w;
241 
242  // Add the uncompressed memory chunk with the game's save data
243  {
245  errCode = writeGameData(&ws).getCode();
246  }
247 
248  if (errCode == Common::kNoError) {
249  w.save(*file, desc);
250  }
251 
252  file->close();
253  return errCode;
254 }
255 
258 
259  int volume = ConfMan.getBool("sfx_mute") ? 0 : CLIP(ConfMan.getInt("sfx_volume"), 0, 255);
261 }
262 
264  _pcSpeaker->speakerOn(50, 50);
265 }
266 
267 } // End of namespace Glk
Blorb * _blorb
Definition: glk.h:115
Simple string class for ScummVM.
Definition: str.h:49
Engine initialization: No game data was found in the specified location.
Definition: error.h:46
unsigned int uint32
Definition: cdtypes.h:26
Sounds * _sounds
Definition: glk.h:124
virtual bool open(const String &filename)
Try to open the file with the given filename, by searching SearchMan.
Definition: file.cpp:41
Pictures manager.
Definition: picture.h:89
Base class for streams.
Definition: streams.h:119
Streams * _streams
Definition: glk.h:123
virtual void runGame()=0
Main game loop for the individual interpreters.
iterator end()
Definition: list.h:218
bool open(Common::SeekableReadStream *stream, uint32 formType=0)
Opens a Quetzal file for access.
Definition: quetzal.cpp:85
virtual InterpreterType getInterpreterType() const =0
Returns the running interpreter type.
void speakerOn(int16 frequency, int32 length=-1)
Definition: pc_speaker.cpp:39
Iterator begin()
Return an iterator for the beginning of the chunks list.
Definition: quetzal.h:136
ErrorCode getCode() const
Get the error code of this error.
Definition: error.h:103
Conf * _conf
Definition: glk.h:117
t_T & front()
Returns a reference to the first element of the list.
Definition: list.h:147
virtual ~GlkEngine()
Definition: glk.cpp:64
iterator begin()
Definition: list.h:210
FILE * file
static const BdfFontData desc
static void getBlorbFilenames(const Common::String &srcFilename, Common::StringArray &filenames, InterpreterType interpType, const Common::String &gameId)
Return a list of possible filenames for blorb files.
Definition: blorb.cpp:266
void close(StreamResult *result=nullptr)
Close and delete the stream.
Definition: streams.cpp:63
Quetzal save file reader.
Definition: quetzal.h:54
Failure to write data – disk full?
Definition: error.h:60
virtual void syncSoundSettings()
Notify the engine that the sound settings in the config manager may have changed and that it hence sh...
Definition: engine.cpp:591
virtual void syncSoundSettings() override
Updates sound settings.
Definition: glk.cpp:256
Audio::Mixer * _mixer
Definition: engine.h:60
Common::WriteStream & add(uint32 chunkId)
Add a chunk.
Definition: quetzal.cpp:191
Common::Language getLanguage() const
Returns the language.
Definition: glk.h:154
void deleteRef(frefid_t fref)
Delete a file reference.
Definition: streams.cpp:1486
Blorb file manager.
Definition: blorb.h:83
void initGraphics(int width, int height, const Graphics::PixelFormat *format)
Definition: engine.cpp:284
Main windows manager.
Definition: windows.h:51
static bool isBlorb(Common::SeekableReadStream &stream, uint32 type=0)
Returns true if a given file is a Blorb file.
Definition: blorb.cpp:226
Definition: engine.h:57
OSystem * g_system
The global OSystem instance.
Definition: system.cpp:40
GlkEngine(OSystem *syst, const GlkGameDescription &gameDesc)
Definition: glk.cpp:48
virtual Common::Error writeGameData(Common::WriteStream *ws)=0
Save the game.
uint16 height
Definition: thumbnail.cpp:41
Common::Error saveGame()
Prompt the user to save their game, and then save it.
Definition: glk.cpp:171
virtual Common::Error saveGameState(int slot, const Common::String &desc) override
Save the game to a given slot.
Definition: glk.cpp:231
File details.
Definition: streams.h:72
void save(Common::WriteStream *out, const Common::String &saveName, uint32 formType=ID_IFSF)
Save the added chunks to file.
Definition: quetzal.cpp:202
#define SearchMan
Shortcut for accessing the search manager.
Definition: archive.h:277
Quetzal save file writer.
Definition: quetzal.h:162
Clipboard * _clipboard
Definition: glk.h:116
static bool exists(const String &filename)
Checks if a given file exists in any of the current default paths, as defined by SearchMan.
Definition: file.cpp:90
virtual void initGraphicsMode()
Setup the video mode.
Definition: glk.cpp:103
#define DebugMan
Shortcut for accessing the debug manager.
Debugger * _debugger
Definition: glk.h:118
const Common::String & getGameID() const
Returns the game&#39;s Id.
Definition: glk.h:164
Events manager.
Definition: events.h:163
void initialize()
Handles basic initialization.
Definition: glk.cpp:79
Overall manager for selecting areas on the screen, copying to/from the clipboard, and managing hyperl...
Definition: selection.h:101
Screen surface class.
Definition: screen.h:44
#define nullptr
Definition: c++11-compat.h:37
Iterator end()
Return an iterator for the beginning of the chunks list.
Definition: quetzal.h:141
Base class for the different interpreters.
Definition: glk.h:71
size_type size() const
Definition: array.h:213
virtual Common::Error loadGameState(int slot) override
Load a savegame from a given slot.
Definition: glk.cpp:184
ErrorCode
This file contains an enum with commonly used error codes.
Definition: error.h:44
FileStream * openFileStream(frefid_t fref, uint fmode, uint rock=0, bool unicode=false)
Open a file stream.
Definition: streams.cpp:1357
Contains the necessary data structures andfunctions for adding to andreferring to the ID table(a very...
Definition: adrift.cpp:28
Sound manager.
Definition: sound.h:97
unsigned int uint
Definition: scummsys.h:440
virtual Common::List< Graphics::PixelFormat > getSupportedFormats() const =0
Returns a list of all pixel formats supported by the backend.
Common::String filename
Definition: action.cpp:479
No error occurred.
Definition: error.h:45
Generic interface for a writable data stream.
Definition: stream.h:64
static uint32 getInterpreterTag(InterpreterType interpType)
Definition: quetzal.cpp:35
GlkEngine * g_vm
Definition: glk.cpp:46
An Error instance pairs an error code with string description providing more details about the error...
Definition: error.h:77
static Common::String readString(Common::ReadStream *src)
Support method for reading a string from a stream.
Definition: quetzal.cpp:180
uint32 readUint32BE()
Read an unsigned 32-bit word stored in big endian (MSB first) order from the stream and return it...
Definition: stream.h:385
virtual Common::Error run()
Init the engine and start its main loop.
Definition: glk.cpp:119
virtual Debugger * createDebugger()
Creates a debugger instance.
Definition: glk.h:106
uint16 width
Definition: thumbnail.cpp:41
const Common::String & getGameMD5() const
Returns the game&#39;s md5.
Definition: glk.h:169
A pixel format description.
Definition: pixelformat.h:136
Screen * _screen
Definition: glk.h:121
PCSpeaker * _pcSpeaker
Definition: glk.h:82
Interface for ScummVM backends.
Definition: system.h:113
virtual Screen * createScreen()
Create the screen.
Definition: glk.cpp:99
void beep()
Generate a beep.
Definition: glk.cpp:263
virtual bool skip(uint32 offset)
TODO: Get rid of this??? Or keep it and document it.
Definition: stream.h:601
#define ConfMan
Shortcut for accessing the configuration manager.
Common::Error loadGame()
Prompt the user for a savegame to load, and then load it.
Definition: glk.cpp:159
Pictures * _pictures
Definition: glk.h:120
Language parseLanguage(const String &str)
Convert a string containing a language name into a Language enum value.
Definition: language.cpp:64
virtual Common::Error readSaveData(Common::SeekableReadStream *rs)=0
Load a savegame from the passed Quetzal file chunk stream.
Failed to read a file (permission denied?)
Definition: error.h:59
Streams manager.
Definition: streams.h:580
virtual void setVolumeForSoundType(SoundType type, int volume)=0
Set the volume for the given sound type.
T CLIP(T v, T amin, T amax)
Definition: util.h:51
Acts as interface to and from the system&#39;s clipboard storage.
Definition: selection.h:41
Windows * _windows
Definition: glk.h:125
Common::File _gameFile
Definition: glk.h:81
Interface for a seekable & readable data stream.
Definition: stream.h:561
frefid_t createByPrompt(uint usage, FileMode fmode, uint rock)
Prompt for a savegame to load or save, and populate a file reference from the result.
Definition: streams.cpp:1419
Selection * _selection
Definition: glk.h:122
Iterator for the chunks list.
Definition: quetzal.h:63
void initialize()
Initialize the screen.
Definition: screen.cpp:41
Engine configuration.
Definition: conf.h:35
const Common::String & getFilename() const
Returns the primary filename for the game.
Definition: glk.h:174
Common::String _description
Definition: streams.h:75
Events * _events
Definition: glk.h:119
PixelFormat format
Definition: thumbnail.cpp:42