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/debugger.h"
36 #include "glk/events.h"
37 #include "glk/picture.h"
38 #include "glk/quetzal.h"
39 #include "glk/screen.h"
40 #include "glk/selection.h"
41 #include "glk/sound.h"
42 #include "glk/streams.h"
43 #include "glk/windows.h"
44 
45 namespace Glk {
46 
48 
50  _gameDescription(gameDesc), Engine(syst), _random("Glk"), _quitFlag(false), _blorb(nullptr),
51  _clipboard(nullptr), _conf(nullptr),_events(nullptr), _pictures(nullptr), _screen(nullptr),
52  _selection(nullptr), _sounds(nullptr), _streams(nullptr), _windows(nullptr),
53  _copySelect(false), _terminated(false), _pcSpeaker(nullptr), _loadSaveSlot(-1),
54  gli_register_obj(nullptr), gli_unregister_obj(nullptr), gli_register_arr(nullptr),
55  gli_unregister_arr(nullptr) {
56  // Set up debug channels
57  DebugMan.addDebugChannel(kDebugCore, "core", "Core engine debug level");
58  DebugMan.addDebugChannel(kDebugScripts, "scripts", "Game scripts");
59  DebugMan.addDebugChannel(kDebugGraphics, "graphics", "Graphics handling");
60  DebugMan.addDebugChannel(kDebugSound, "sound", "Sound and Music handling");
61 
62  g_vm = this;
63 }
64 
66  delete _blorb;
67  delete _clipboard;
68  delete _conf;
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  setDebugger(new Debugger());
82 
83  _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 
117 }
118 
120  // Open up the game file
124 
125  if (Blorb::isBlorb(filename)) {
126  // Blorb archive
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;
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 
231 Common::Error GlkEngine::saveGameState(int slot, const Common::String &desc, bool isAutosave) {
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
Glk::GlkEngine::beep
void beep()
Generate a beep.
Definition: glk.cpp:263
Common::SeekableReadStream
Interface for a seekable & readable data stream.
Definition: stream.h:569
selection.h
Glk
Contains the necessary data structures andfunctions for adding to andreferring to the ID table(a very...
Definition: adrift.cpp:28
windows.h
Glk::GlkEngine::writeGameData
virtual Common::Error writeGameData(Common::WriteStream *ws)=0
Save the game.
Common::Array< String >
Common::ReadStream::readUint32BE
uint32 readUint32BE()
Read an unsigned 32-bit word stored in big endian (MSB first) order from the stream and return it.
Definition: stream.h:393
Glk::FileReference::_description
Common::String _description
Definition: streams.h:75
scummsys.h
Engine
Definition: engine.h:60
Glk::ID_IFSF
Definition: quetzal.h:37
Glk::QuetzalReader::Iterator
Iterator for the chunks list.
Definition: quetzal.h:63
Glk::GlkEngine::createScreen
virtual Screen * createScreen()
Create the screen.
Definition: glk.cpp:99
Glk::GlkEngine::loadGame
Common::Error loadGame()
Prompt the user for a savegame to load, and then load it.
Definition: glk.cpp:159
Common::File::open
virtual bool open(const String &filename)
Try to open the file with the given filename, by searching SearchMan.
Definition: file.cpp:41
Glk::Debugger
Definition: debugger.h:35
streams.h
Glk::Events
Events manager.
Definition: events.h:163
Glk::QuetzalWriter
Quetzal save file writer.
Definition: quetzal.h:162
Glk::Screen
Screen surface class.
Definition: screen.h:44
sound.h
Glk::GlkEngine::_pictures
Pictures * _pictures
Definition: glk.h:111
Glk::Streams
Streams manager.
Definition: streams.h:580
Glk::QuetzalWriter::save
void save(Common::WriteStream *out, const Common::String &saveName, uint32 formType=ID_IFSF)
Save the added chunks to file.
Definition: quetzal.cpp:204
util.h
Glk::Pictures
Pictures manager.
Definition: picture.h:89
Glk::ID_UMem
Definition: quetzal.h:40
Glk::GlkEngine::_windows
Windows * _windows
Definition: glk.h:116
Glk::Conf
Engine configuration.
Definition: conf.h:35
Engine::setDebugger
void setDebugger(GUI::Debugger *debugger)
Sets the engine's debugger.
Definition: engine.h:196
Glk::JACL::it
int it
Definition: jacl_main.cpp:56
Common::Array::size
size_type size() const
Definition: array.h:213
Common::String
Simple string class for ScummVM.
Definition: str.h:49
Supernova::CLIP
Definition: msn_def.h:132
height
uint16 height
Definition: thumbnail.cpp:41
config-manager.h
file.h
Glk::FileReference
File details.
Definition: streams.h:72
uint32
unsigned int uint32
Definition: cdtypes.h:26
Glk::GlkEngine::getGameID
const Common::String & getGameID() const
Returns the game's Id.
Definition: glk.h:155
Glk::g_vm
GlkEngine * g_vm
Definition: glk.cpp:47
Common::Error
An Error instance pairs an error code with string description providing more details about the error.
Definition: error.h:77
Glk::QuetzalReader::begin
Iterator begin()
Return an iterator for the beginning of the chunks list.
Definition: quetzal.h:136
events.h
Common::kReadingFailed
Failed to read a file (permission denied?)
Definition: error.h:59
Glk::GlkEngine::_gameFile
Common::File _gameFile
Definition: glk.h:80
glk.h
Glk::GlkEngine::loadGameState
Common::Error loadGameState(int slot) override
Load a savegame from a given slot.
Definition: glk.cpp:184
Glk::Blorb
Blorb file manager.
Definition: blorb.h:83
Glk::kDebugGraphics
Definition: glk.h:51
Glk::Streams::openFileStream
FileStream * openFileStream(frefid_t fref, uint fmode, uint rock=0, bool unicode=false)
Open a file stream.
Definition: streams.cpp:1357
Glk::QuetzalBase::getInterpreterTag
static uint32 getInterpreterTag(InterpreterType interpType)
Definition: quetzal.cpp:35
width
uint16 width
Definition: thumbnail.cpp:41
Glk::fileusage_TextMode
Definition: streams.h:46
Glk::Streams::createByPrompt
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
Engine::syncSoundSettings
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:627
blorb.h
Glk::FileReference::_slotNumber
int _slotNumber
Definition: streams.h:74
thumbnail.h
Glk::kDebugScripts
Definition: glk.h:50
Glk::Streams::deleteRef
void deleteRef(frefid_t fref)
Delete a file reference.
Definition: streams.cpp:1486
Common::kWritingFailed
Failure to write data – disk full?
Definition: error.h:60
Glk::kDebugSound
Definition: glk.h:52
Glk::GlkEngine::_screen
Screen * _screen
Definition: glk.h:112
language.h
Glk::PCSpeaker::speakerOn
void speakerOn(int16 frequency, int32 length=-1)
Definition: pc_speaker.cpp:39
Glk::GlkEngine::_pcSpeaker
PCSpeaker * _pcSpeaker
Definition: glk.h:81
Glk::GlkEngine::_streams
Streams * _streams
Definition: glk.h:114
Glk::GlkEngine::runGame
virtual void runGame()=0
Main game loop for the individual interpreters.
Glk::fileusage_BinaryMode
Definition: streams.h:47
format
PixelFormat format
Definition: thumbnail.cpp:42
OSystem::getSupportedFormats
virtual Common::List< Graphics::PixelFormat > getSupportedFormats() const =0
Returns a list of all pixel formats supported by the backend.
Engine::_mixer
Audio::Mixer * _mixer
Definition: engine.h:63
Common::List::end
iterator end()
Definition: list.h:218
OPL::DOSBox::DBOPL::volume
Bitu volume
Definition: dbopl.h:66
screen.h
conf.h
Glk::GlkEngine::_conf
Conf * _conf
Definition: glk.h:109
Glk::Blorb::getBlorbFilenames
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
Glk::GlkEngine::readSaveData
virtual Common::Error readSaveData(Common::SeekableReadStream *rs)=0
Load a savegame from the passed Quetzal file chunk stream.
Common::File::exists
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
LastExpress::false
IMPLEMENT_FUNCTION_END false
Definition: chapters.cpp:111
Audio::Mixer::setVolumeForSoundType
virtual void setVolumeForSoundType(SoundType type, int volume)=0
Set the volume for the given sound type.
Glk::GlkEngine::_events
Events * _events
Definition: glk.h:110
Glk::Clipboard
Acts as interface to and from the system's clipboard storage.
Definition: selection.h:41
uint
unsigned int uint
Definition: scummsys.h:440
Glk::QuetzalReader::readString
static Common::String readString(Common::ReadStream *src)
Support method for reading a string from a stream.
Definition: quetzal.cpp:182
picture.h
Glk::GlkEngine::getLanguage
Common::Language getLanguage() const
Returns the language.
Definition: glk.h:145
Glk::GlkEngine::saveGame
Common::Error saveGame()
Prompt the user to save their game, and then save it.
Definition: glk.cpp:171
Common::List< Graphics::PixelFormat >
Glk::Level9::_screen
void _screen()
Definition: level9_main.cpp:2162
Glk::Sounds
Sound manager.
Definition: sound.h:100
Common::ErrorCode
ErrorCode
This file contains an enum with commonly used error codes.
Definition: error.h:44
Glk::GlkEngine::GlkEngine
GlkEngine(OSystem *syst, const GlkGameDescription &gameDesc)
Definition: glk.cpp:49
Common::WriteStream
Generic interface for a writable data stream.
Definition: stream.h:65
Common::Error::getCode
ErrorCode getCode() const
Get the error code of this error.
Definition: error.h:103
Glk::GlkEngine::initGraphicsMode
virtual void initGraphicsMode()
Setup the video mode.
Definition: glk.cpp:103
Glk::QuetzalReader::end
Iterator end()
Return an iterator for the beginning of the chunks list.
Definition: quetzal.h:141
Glk::GlkEngine::_blorb
Blorb * _blorb
Definition: glk.h:107
Glk::kDebugCore
Definition: glk.h:49
Glk::GlkEngine::_selection
Selection * _selection
Definition: glk.h:113
Glk::GlkEngine::getFilename
const Common::String & getFilename() const
Returns the primary filename for the game.
Definition: glk.h:165
Glk::Stream
Base class for streams.
Definition: streams.h:119
Glk::Selection
Overall manager for selecting areas on the screen, copying to/from the clipboard, and managing hyperl...
Definition: selection.h:101
Glk::Windows
Main windows manager.
Definition: windows.h:51
Glk::GlkEngine::_sounds
Sounds * _sounds
Definition: glk.h:115
Glk::PCSpeaker
Definition: pc_speaker.h:34
Audio::Mixer::kPlainSoundType
Definition: mixer.h:56
Glk::ID_SCVM
Definition: quetzal.h:43
Glk::GlkEngine::_clipboard
Clipboard * _clipboard
Definition: glk.h:108
Graphics::desc
static const BdfFontData desc
Definition: consolefont.cpp:5852
Glk::GlkEngine::initialize
void initialize()
Handles basic initialization.
Definition: glk.cpp:79
Glk::GlkEngine::saveGameState
Common::Error saveGameState(int slot, const Common::String &desc, bool isAutosave=false) override
Save the game to a given slot.
Definition: glk.cpp:231
Common::List::begin
iterator begin()
Definition: list.h:210
Glk::Blorb::isBlorb
static bool isBlorb(Common::SeekableReadStream &stream, uint32 type=0)
Returns true if a given file is a Blorb file.
Definition: blorb.cpp:226
OSystem
Interface for ScummVM backends.
Definition: system.h:114
Glk::GlkEngine::getInterpreterType
virtual InterpreterType getInterpreterType() const =0
Returns the running interpreter type.
Common::kNoError
No error occurred.
Definition: error.h:45
Common::kNoGameDataFoundError
Engine initialization: No game data was found in the specified location.
Definition: error.h:46
events.h
Common::List::front
t_T & front()
Returns a reference to the first element of the list.
Definition: list.h:147
initGraphics
void initGraphics(int width, int height, const Graphics::PixelFormat *format)
Definition: engine.cpp:288
Common::parseLanguage
Language parseLanguage(const String &str)
Convert a string containing a language name into a Language enum value.
Definition: language.cpp:65
Glk::GlkEngine::syncSoundSettings
void syncSoundSettings() override
Updates sound settings.
Definition: glk.cpp:256
g_system
OSystem * g_system
The global OSystem instance.
Definition: system.cpp:40
Glk::JACL::file
FILE * file
debugger.h
Glk::filemode_Read
Definition: streams.h:52
Glk::fileusage_SavedGame
Definition: streams.h:41
Graphics::PixelFormat
A pixel format description.
Definition: pixelformat.h:136
Glk::GlkEngine
Base class for the different interpreters.
Definition: glk.h:70
debug-channels.h
Glk::filemode_Write
Definition: streams.h:51
Glk::QuetzalReader::open
bool open(Common::SeekableReadStream *stream, uint32 formType=0)
Opens a Quetzal file for access.
Definition: quetzal.cpp:87
quetzal.h
Glk::GlkEngine::run
Common::Error run() override
Init the engine and start its main loop.
Definition: glk.cpp:119
filename
Common::String filename
Definition: action.cpp:1197
Common::ListInternal::Iterator
Definition: list_intern.h:49
Glk::QuetzalReader
Quetzal save file reader.
Definition: quetzal.h:54
Glk::GlkGameDescription
Definition: glk.h:58
Glk::Screen::initialize
void initialize()
Initialize the screen.
Definition: screen.cpp:41
Glk::GlkEngine::~GlkEngine
~GlkEngine() override
Definition: glk.cpp:65
Glk::QuetzalWriter::add
Common::WriteStream & add(uint32 chunkId)
Add a chunk.
Definition: quetzal.cpp:193
Common::SeekableReadStream::skip
virtual bool skip(uint32 offset)
TODO: Get rid of this??? Or keep it and document it.
Definition: stream.h:609
Glk::GlkEngine::getGameMD5
const Common::String & getGameMD5() const
Returns the game's md5.
Definition: glk.h:160