aboutsummaryrefslogtreecommitdiff
path: root/engines/sword25
diff options
context:
space:
mode:
authorMatthew Hoops2011-06-03 01:14:16 -0400
committerMatthew Hoops2011-06-03 01:14:16 -0400
commit224c71e483e09931ba386555ff3b436b9defe63d (patch)
tree8e6178331a7bbd3ee1be318d3fc7a7c7f478468f /engines/sword25
parentd4c92983920cfe3b25a22d91e12c750e591b917e (diff)
parent547fd1bdcabcba0e741eb31100ba99ff73399d24 (diff)
downloadscummvm-rg350-224c71e483e09931ba386555ff3b436b9defe63d.tar.gz
scummvm-rg350-224c71e483e09931ba386555ff3b436b9defe63d.tar.bz2
scummvm-rg350-224c71e483e09931ba386555ff3b436b9defe63d.zip
Merge remote branch 'upstream/master' into pegasus
Diffstat (limited to 'engines/sword25')
-rw-r--r--engines/sword25/detection.cpp35
-rw-r--r--engines/sword25/detection_tables.h129
-rw-r--r--engines/sword25/fmv/movieplayer.cpp2
-rw-r--r--engines/sword25/fmv/theora_decoder.cpp27
-rw-r--r--engines/sword25/fmv/theora_decoder.h9
-rw-r--r--engines/sword25/gfx/graphicengine.h2
-rw-r--r--engines/sword25/gfx/image/imgloader.cpp85
-rw-r--r--engines/sword25/gfx/image/imgloader.h (renamed from engines/sword25/gfx/image/pngloader.h)39
-rw-r--r--engines/sword25/gfx/image/pngloader.cpp245
-rw-r--r--engines/sword25/gfx/image/renderedimage.cpp52
-rw-r--r--engines/sword25/gfx/image/swimage.cpp12
-rw-r--r--engines/sword25/gfx/panel.cpp4
-rw-r--r--engines/sword25/gfx/screenshot.cpp7
-rw-r--r--engines/sword25/input/inputengine.h2
-rw-r--r--engines/sword25/kernel/kernel.cpp2
-rw-r--r--engines/sword25/kernel/kernel.h2
-rw-r--r--engines/sword25/kernel/persistenceservice.cpp4
-rw-r--r--engines/sword25/math/polygon.cpp2
-rw-r--r--engines/sword25/math/polygon.h6
-rw-r--r--engines/sword25/math/region.cpp2
-rw-r--r--engines/sword25/math/region.h4
-rw-r--r--engines/sword25/math/vertex.h3
-rw-r--r--engines/sword25/math/walkregion.cpp6
-rw-r--r--engines/sword25/module.mk6
-rw-r--r--engines/sword25/script/luascript.cpp4
-rw-r--r--engines/sword25/script/luascript.h5
-rw-r--r--engines/sword25/script/script.h2
-rw-r--r--engines/sword25/sfx/soundengine.h2
-rw-r--r--engines/sword25/sword25.cpp4
-rw-r--r--engines/sword25/sword25.h2
-rw-r--r--engines/sword25/util/lua/lapi.cpp16
-rw-r--r--engines/sword25/util/lua/lauxlib.cpp45
-rw-r--r--engines/sword25/util/lua/ldo.cpp30
-rw-r--r--engines/sword25/util/lua/ldump.cpp164
-rw-r--r--engines/sword25/util/lua/liolib.cpp226
-rw-r--r--engines/sword25/util/lua/llex.cpp19
-rw-r--r--engines/sword25/util/lua/lmathlib.cpp4
-rw-r--r--engines/sword25/util/lua/loadlib.cpp197
-rw-r--r--engines/sword25/util/lua/loslib.cpp42
-rw-r--r--engines/sword25/util/lua/lua.h2
-rw-r--r--engines/sword25/util/lua/luaconf.h10
-rw-r--r--engines/sword25/util/lua/lundump.cpp225
-rw-r--r--engines/sword25/util/lua/lundump.h36
-rw-r--r--engines/sword25/util/lua/lvm.cpp2
-rw-r--r--engines/sword25/util/lua/print.cpp227
-rw-r--r--engines/sword25/util/lua/scummvm_file.cpp205
-rw-r--r--engines/sword25/util/lua/scummvm_file.h56
47 files changed, 828 insertions, 1384 deletions
diff --git a/engines/sword25/detection.cpp b/engines/sword25/detection.cpp
index caa1cf51ac..edb8c30545 100644
--- a/engines/sword25/detection.cpp
+++ b/engines/sword25/detection.cpp
@@ -24,6 +24,7 @@
#include "engines/advancedDetector.h"
#include "sword25/sword25.h"
+#include "sword25/detection_tables.h"
#include "sword25/kernel/persistenceservice.h"
namespace Sword25 {
@@ -35,38 +36,6 @@ static const PlainGameDescriptor Sword25Game[] = {
{0, 0}
};
-namespace Sword25 {
-
-// TODO: Need to decide whether we're going to implement code to detect all the various languages allowed,
-// both by the core data package, as well as the extra languages added by the patch file; also, I don't
-// think that all the languages supported by the game currently have constants in ScummVM
-static const ADGameDescription gameDescriptions[] = {
- {
- "sword25",
- "",
- AD_ENTRY1s("data.b25c", "f8b6e03ada2d2f6cf27fbc11ad1572e9", 654310588),
- Common::EN_ANY,
- Common::kPlatformUnknown,
- ADGF_NO_FLAGS,
- Common::GUIO_NONE
- },
- {
- "sword25",
- "Extracted",
- {{"_includes.lua", 0, 0, -1},
- {"boot.lua", 0, 0, -1},
- {"kernel.lua", 0, 0, -1},
- AD_LISTEND},
- Common::EN_ANY,
- Common::kPlatformUnknown,
- GF_EXTRACTED,
- Common::GUIO_NONE
- },
- AD_TABLE_END_MARKER
-};
-
-} // End of namespace Sword25
-
static const char *directoryGlobs[] = {
"system", // Used by extracted dats
0
@@ -102,7 +71,7 @@ public:
Sword25MetaEngine() : AdvancedMetaEngine(detectionParams) {}
virtual const char *getName() const {
- return "Broken Sword 2.5";
+ return "Sword25";
}
virtual const char *getOriginalCopyright() const {
diff --git a/engines/sword25/detection_tables.h b/engines/sword25/detection_tables.h
new file mode 100644
index 0000000000..ca586b4f01
--- /dev/null
+++ b/engines/sword25/detection_tables.h
@@ -0,0 +1,129 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+namespace Sword25 {
+
+using Common::GUIO_NONE;
+using Common::GUIO_NOSPEECH;
+using Common::GUIO_NOSFX;
+using Common::GUIO_NOMUSIC;
+
+static const ADGameDescription gameDescriptions[] = {
+ {
+ "sword25",
+ "",
+ AD_ENTRY1s("data.b25c", "f8b6e03ada2d2f6cf27fbc11ad1572e9", 654310588),
+ Common::EN_ANY,
+ Common::kPlatformUnknown,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ {
+ "sword25",
+ "",
+ AD_ENTRY1s("lang_fr.b25c", "690caf157387e06d2c3d1ca53c43f428", 1006043),
+ Common::FR_FRA,
+ Common::kPlatformUnknown,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ {
+ "sword25",
+ "",
+ AD_ENTRY1s("data.b25c", "f8b6e03ada2d2f6cf27fbc11ad1572e9", 654310588),
+ Common::DE_DEU,
+ Common::kPlatformUnknown,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ {
+ "sword25",
+ "",
+ AD_ENTRY1s("lang_hr.b25c", "e881054d1f8ec1e527422fc521c25405", 1273217),
+ Common::HU_HUN,
+ Common::kPlatformUnknown,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ {
+ "sword25",
+ "",
+ AD_ENTRY1s("lang_it.b25c", "f3325666da0515cc2b42062e953c0889", 996197),
+ Common::IT_ITA,
+ Common::kPlatformUnknown,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ {
+ "sword25",
+ "",
+ AD_ENTRY1s("lang_pl.b25c", "49dc1a20f95391a808e475c49be2bac0", 1281799),
+ Common::PL_POL,
+ Common::kPlatformUnknown,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ {
+ "sword25",
+ "",
+ AD_ENTRY1s("lang_pt.b25c", "1df701432f9e13dcefe1adeb890b9c69", 993812),
+ Common::PT_BRA,
+ Common::kPlatformUnknown,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ {
+ "sword25",
+ "",
+ AD_ENTRY1s("lang_ru.b25c", "deb33dd2f90a71ff60181918a8ce5063", 1235378),
+ Common::RU_RUS,
+ Common::kPlatformUnknown,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+ {
+ "sword25",
+ "",
+ AD_ENTRY1s("lang_es.b25c", "384c19072d83725f351bb9ecb4d3f02b", 987965),
+ Common::ES_ESP,
+ Common::kPlatformUnknown,
+ ADGF_NO_FLAGS,
+ Common::GUIO_NONE
+ },
+
+ // Extracted version
+ {
+ "sword25",
+ "Extracted",
+ {{"_includes.lua", 0, 0, -1},
+ {"boot.lua", 0, 0, -1},
+ {"kernel.lua", 0, 0, -1},
+ AD_LISTEND},
+ Common::EN_ANY,
+ Common::kPlatformUnknown,
+ GF_EXTRACTED,
+ Common::GUIO_NONE
+ },
+ AD_TABLE_END_MARKER
+};
+
+} // End of namespace Sword25
diff --git a/engines/sword25/fmv/movieplayer.cpp b/engines/sword25/fmv/movieplayer.cpp
index d267506ae2..d0ad41de22 100644
--- a/engines/sword25/fmv/movieplayer.cpp
+++ b/engines/sword25/fmv/movieplayer.cpp
@@ -145,7 +145,7 @@ bool MoviePlayer::isMovieLoaded() {
}
bool MoviePlayer::isPaused() {
- return _decoder.isPaused();
+ return _decoder.isPaused() || _decoder.endOfVideo();
}
float MoviePlayer::getScaleFactor() {
diff --git a/engines/sword25/fmv/theora_decoder.cpp b/engines/sword25/fmv/theora_decoder.cpp
index 07cb56356d..be6d940d23 100644
--- a/engines/sword25/fmv/theora_decoder.cpp
+++ b/engines/sword25/fmv/theora_decoder.cpp
@@ -54,7 +54,6 @@ static double rint(double v) {
TheoraDecoder::TheoraDecoder(Audio::Mixer::SoundType soundType) {
_fileStream = 0;
- _surface = 0;
_theoraPacket = 0;
_vorbisPacket = 0;
@@ -298,8 +297,14 @@ bool TheoraDecoder::loadStream(Common::SeekableReadStream *stream) {
_endOfAudio = true;
}
- _surface = new Graphics::Surface();
- _surface->create(_theoraInfo.frame_width, _theoraInfo.frame_height, g_system->getScreenFormat());
+ _surface.create(_theoraInfo.frame_width, _theoraInfo.frame_height, g_system->getScreenFormat());
+
+ // Set up a display surface
+ _displaySurface.pixels = _surface.getBasePtr(_theoraInfo.pic_x, _theoraInfo.pic_y);
+ _displaySurface.w = _theoraInfo.pic_width;
+ _displaySurface.h = _theoraInfo.pic_height;
+ _displaySurface.format = _surface.format;
+ _displaySurface.pitch = _surface.pitch;
// Set the frame rate
_frameRate = Common::Rational(_theoraInfo.fps_numerator, _theoraInfo.fps_denominator);
@@ -337,9 +342,9 @@ void TheoraDecoder::close() {
delete _fileStream;
_fileStream = 0;
- _surface->free();
- delete _surface;
- _surface = 0;
+ _surface.free();
+ _displaySurface.pixels = 0;
+ _displaySurface.free();
reset();
}
@@ -412,7 +417,7 @@ const Graphics::Surface *TheoraDecoder::decodeNextFrame() {
}
}
- return _surface;
+ return &_displaySurface;
}
bool TheoraDecoder::queueAudio() {
@@ -440,7 +445,11 @@ bool TheoraDecoder::queueAudio() {
_audiobufFill += (i * _vorbisInfo.channels) << 1;
if (_audiobufFill == AUDIOFD_FRAGSIZE) {
- _audStream->queueBuffer((byte *)_audiobuf, AUDIOFD_FRAGSIZE, DisposeAfterUse::NO, Audio::FLAG_16BITS | Audio::FLAG_LITTLE_ENDIAN | Audio::FLAG_STEREO);
+ byte flags = Audio::FLAG_16BITS | Audio::FLAG_STEREO;
+#ifdef SCUMM_LITTLE_ENDIAN
+ flags |= Audio::FLAG_LITTLE_ENDIAN;
+#endif
+ _audStream->queueBuffer((byte *)_audiobuf, AUDIOFD_FRAGSIZE, DisposeAfterUse::NO, flags);
// The audio mixer is now responsible for the old audio buffer.
// We need to create a new one.
@@ -533,7 +542,7 @@ void TheoraDecoder::translateYUVtoRGBA(th_ycbcr_buffer &YUVBuffer) {
assert(YUVBuffer[kBufferU].height == YUVBuffer[kBufferY].height >> 1);
assert(YUVBuffer[kBufferV].height == YUVBuffer[kBufferY].height >> 1);
- Graphics::convertYUV420ToRGB(_surface, YUVBuffer[kBufferY].data, YUVBuffer[kBufferU].data, YUVBuffer[kBufferV].data, YUVBuffer[kBufferY].width, YUVBuffer[kBufferY].height, YUVBuffer[kBufferY].stride, YUVBuffer[kBufferU].stride);
+ Graphics::convertYUV420ToRGB(&_surface, YUVBuffer[kBufferY].data, YUVBuffer[kBufferU].data, YUVBuffer[kBufferV].data, YUVBuffer[kBufferY].width, YUVBuffer[kBufferY].height, YUVBuffer[kBufferY].stride, YUVBuffer[kBufferU].stride);
}
} // End of namespace Sword25
diff --git a/engines/sword25/fmv/theora_decoder.h b/engines/sword25/fmv/theora_decoder.h
index 10a05647c3..e8cc5ab8b9 100644
--- a/engines/sword25/fmv/theora_decoder.h
+++ b/engines/sword25/fmv/theora_decoder.h
@@ -70,8 +70,8 @@ public:
const Graphics::Surface *decodeNextFrame();
bool isVideoLoaded() const { return _fileStream != 0; }
- uint16 getWidth() const { return _surface->w; }
- uint16 getHeight() const { return _surface->h; }
+ uint16 getWidth() const { return _displaySurface.w; }
+ uint16 getHeight() const { return _displaySurface.h; }
uint32 getFrameCount() const {
// It is not possible to get frame count easily
@@ -80,7 +80,7 @@ public:
return 0;
}
- Graphics::PixelFormat getPixelFormat() const { return _surface->format; }
+ Graphics::PixelFormat getPixelFormat() const { return _displaySurface.format; }
uint32 getElapsedTime() const;
uint32 getTimeToNextFrame() const;
@@ -96,7 +96,8 @@ private:
void translateYUVtoRGBA(th_ycbcr_buffer &YUVBuffer);
Common::SeekableReadStream *_fileStream;
- Graphics::Surface *_surface;
+ Graphics::Surface _surface;
+ Graphics::Surface _displaySurface;
Common::Rational _frameRate;
double _nextFrameStartTime;
bool _endOfVideo;
diff --git a/engines/sword25/gfx/graphicengine.h b/engines/sword25/gfx/graphicengine.h
index 04826c2e5a..3309763966 100644
--- a/engines/sword25/gfx/graphicengine.h
+++ b/engines/sword25/gfx/graphicengine.h
@@ -106,7 +106,7 @@ public:
// ---------
/**
- * Initialises the graphics engine and sets the screen mode. Returns
+ * Initializes the graphics engine and sets the screen mode. Returns
* true if initialisation failed.
* @note This method should be called immediately after the
* initialisation of all services.
diff --git a/engines/sword25/gfx/image/imgloader.cpp b/engines/sword25/gfx/image/imgloader.cpp
new file mode 100644
index 0000000000..1df0fba70c
--- /dev/null
+++ b/engines/sword25/gfx/image/imgloader.cpp
@@ -0,0 +1,85 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+/*
+ * This code is based on Broken Sword 2.5 engine
+ *
+ * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
+ *
+ * Licensed under GNU GPL v2
+ *
+ */
+
+#include "common/memstream.h"
+#include "sword25/gfx/image/image.h"
+#include "sword25/gfx/image/imgloader.h"
+#include "graphics/pixelformat.h"
+#include "graphics/png.h"
+
+namespace Sword25 {
+
+bool ImgLoader::decodePNGImage(const byte *fileDataPtr, uint fileSize, byte *&uncompressedDataPtr, int &width, int &height, int &pitch) {
+ Common::MemoryReadStream *fileStr = new Common::MemoryReadStream(fileDataPtr, fileSize, DisposeAfterUse::NO);
+ Graphics::PNG *png = new Graphics::PNG();
+ if (!png->read(fileStr)) // the fileStr pointer, and thus pFileData will be deleted after this is done
+ error("Error while reading PNG image");
+
+ Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
+ Graphics::Surface *pngSurface = png->getSurface(format);
+
+ width = pngSurface->w;
+ height = pngSurface->h;
+ uncompressedDataPtr = new byte[pngSurface->pitch * pngSurface->h];
+ memcpy(uncompressedDataPtr, (byte *)pngSurface->pixels, pngSurface->pitch * pngSurface->h);
+ pngSurface->free();
+
+ delete pngSurface;
+ delete png;
+
+ // Signal success
+ return true;
+}
+
+bool ImgLoader::decodeThumbnailImage(const byte *pFileData, uint fileSize, byte *&pUncompressedData, int &width, int &height, int &pitch) {
+ const byte *src = pFileData + 4; // skip header
+ width = READ_LE_UINT16(src); src += 2;
+ height = READ_LE_UINT16(src); src += 2;
+ src++; // version, ignored for now
+ pitch = width * 4;
+
+ uint32 totalSize = pitch * height;
+ pUncompressedData = new byte[totalSize];
+ uint32 *dst = (uint32 *)pUncompressedData; // treat as uint32, for pixelformat output
+ const Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
+ byte r, g, b;
+
+ for (uint32 i = 0; i < totalSize / 4; i++) {
+ r = *src++;
+ g = *src++;
+ b = *src++;
+ *dst++ = format.RGBToColor(r, g, b);
+ }
+
+ return true;
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/gfx/image/pngloader.h b/engines/sword25/gfx/image/imgloader.h
index 6b5f65ff57..735ab9203c 100644
--- a/engines/sword25/gfx/image/pngloader.h
+++ b/engines/sword25/gfx/image/imgloader.h
@@ -29,30 +29,22 @@
*
*/
-#ifndef SWORD25_PNGLOADER2_H
-#define SWORD25_PNGLOADER2_H
+#ifndef SWORD25_IMGLOADER_H
+#define SWORD25_IMGLOADER_H
#include "sword25/kernel/common.h"
#include "sword25/gfx/graphicengine.h"
namespace Sword25 {
-// Define to use ScummVM's PNG decoder, instead of libpng
-#define USE_INTERNAL_PNG_DECODER
-
/**
* Class for loading PNG files, and PNG data embedded into savegames.
*
* Originally written by Malte Thiesen.
*/
-class PNGLoader {
+class ImgLoader {
protected:
- PNGLoader() {} // Protected constructor to prevent instances
-
- static bool doDecodeImage(const byte *fileDataPtr, uint fileSize, byte *&uncompressedDataPtr, int &width, int &height, int &pitch);
-#ifndef USE_INTERNAL_PNG_DECODER
- static bool doImageProperties(const byte *fileDataPtr, uint fileSize, int &width, int &height);
-#endif
+ ImgLoader() {} // Protected constructor to prevent instances
public:
@@ -70,28 +62,15 @@ public:
* @remark This function does not free the image buffer passed to it,
* it is the callers responsibility to do so.
*/
- static bool decodeImage(const byte *pFileData, uint fileSize,
+ static bool decodePNGImage(const byte *pFileData, uint fileSize,
byte *&pUncompressedData,
int &width, int &height,
int &pitch);
-#ifndef USE_INTERNAL_PNG_DECODER
- /**
- * Extract the properties of an image.
- * @param[in] fileDatePtr pointer to the image data
- * @param[in] fileSize size of the image data in bytes
- * @param[out] width if successful, this is set to the width of the image
- * @param[out] height if successful, this is set to the height of the image
- * @return returns true if extraction of the properties was successful, false in case of an error
- *
- * @remark This function does not free the image buffer passed to it,
- * it is the callers responsibility to do so.
- */
- static bool imageProperties(const byte *fileDatePtr, uint fileSize,
- int &width,
- int &height);
-#endif
-
+ static bool decodeThumbnailImage(const byte *pFileData, uint fileSize,
+ byte *&pUncompressedData,
+ int &width, int &height,
+ int &pitch);
};
} // End of namespace Sword25
diff --git a/engines/sword25/gfx/image/pngloader.cpp b/engines/sword25/gfx/image/pngloader.cpp
deleted file mode 100644
index 6f370d8861..0000000000
--- a/engines/sword25/gfx/image/pngloader.cpp
+++ /dev/null
@@ -1,245 +0,0 @@
-/* ScummVM - Graphic Adventure Engine
- *
- * ScummVM is the legal property of its developers, whose names
- * are too numerous to list here. Please refer to the COPYRIGHT
- * file distributed with this source distribution.
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
-
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
-
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- */
-
-/*
- * This code is based on Broken Sword 2.5 engine
- *
- * Copyright (c) Malte Thiesen, Daniel Queteschiner and Michael Elsdoerfer
- *
- * Licensed under GNU GPL v2
- *
- */
-
-#ifndef USE_INTERNAL_PNG_DECODER
-// Disable symbol overrides so that we can use png.h
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
-#endif
-
-#include "common/memstream.h"
-#include "sword25/gfx/image/image.h"
-#include "sword25/gfx/image/pngloader.h"
-#ifndef USE_INTERNAL_PNG_DECODER
-#include <png.h>
-#else
-#include "graphics/pixelformat.h"
-#include "graphics/png.h"
-#endif
-
-namespace Sword25 {
-
-#ifndef USE_INTERNAL_PNG_DECODER
-static void png_user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) {
- const byte **ref = (const byte **)png_get_io_ptr(png_ptr);
- memcpy(data, *ref, length);
- *ref += length;
-}
-
-static bool doIsCorrectImageFormat(const byte *fileDataPtr, uint fileSize) {
- return (fileSize > 8) && png_check_sig(const_cast<byte *>(fileDataPtr), 8);
-}
-#endif
-
-bool PNGLoader::doDecodeImage(const byte *fileDataPtr, uint fileSize, byte *&uncompressedDataPtr, int &width, int &height, int &pitch) {
-#ifndef USE_INTERNAL_PNG_DECODER
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
-
- int bitDepth;
- int colorType;
- int interlaceType;
- int i;
-
- // Check for valid PNG signature
- if (!doIsCorrectImageFormat(fileDataPtr, fileSize)) {
- error("png_check_sig failed");
- }
-
- // Create both PNG structures
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!png_ptr) {
- error("Could not create libpng read struct.");
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- error("Could not create libpng info struct.");
- }
-
- // Use alternative reading function
- const byte **ref = &fileDataPtr;
- png_set_read_fn(png_ptr, (void *)ref, png_user_read_data);
-
- // Read PNG header
- png_read_info(png_ptr, info_ptr);
-
- // Read out PNG informations
-
- png_uint_32 w, h;
- png_get_IHDR(png_ptr, info_ptr, &w, &h, &bitDepth, &colorType, &interlaceType, NULL, NULL);
- width = w;
- height = h;
-
- // Calculate pitch of output image
- pitch = GraphicEngine::calcPitch(GraphicEngine::CF_ARGB32, width);
-
- // Allocate memory for the final image data.
- // To keep memory framentation low this happens before allocating memory for temporary image data.
- uncompressedDataPtr = new byte[pitch * height];
- if (!uncompressedDataPtr) {
- error("Could not allocate memory for output image.");
- }
-
- // Images of all color formates will be transformed into ARGB images
- if (bitDepth == 16)
- png_set_strip_16(png_ptr);
- if (colorType == PNG_COLOR_TYPE_PALETTE)
- png_set_expand(png_ptr);
- if (bitDepth < 8)
- png_set_expand(png_ptr);
- if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
- png_set_expand(png_ptr);
- if (colorType == PNG_COLOR_TYPE_GRAY ||
- colorType == PNG_COLOR_TYPE_GRAY_ALPHA)
- png_set_gray_to_rgb(png_ptr);
-
- png_set_bgr(png_ptr);
-
- if (colorType != PNG_COLOR_TYPE_RGB_ALPHA)
- png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
-
- // After the transformations have been registered, the image data is read again.
- png_read_update_info(png_ptr, info_ptr);
- png_get_IHDR(png_ptr, info_ptr, &w, &h, &bitDepth, &colorType, NULL, NULL, NULL);
- width = w;
- height = h;
-
- if (interlaceType == PNG_INTERLACE_NONE) {
- // PNGs without interlacing can simply be read row by row.
- for (i = 0; i < height; i++) {
- png_read_row(png_ptr, uncompressedDataPtr + i * pitch, NULL);
- }
- } else {
- // PNGs with interlacing require us to allocate an auxillary
- // buffer with pointers to all row starts.
-
- // Allocate row pointer buffer
- png_bytep *pRowPtr = new png_bytep[height];
- if (!pRowPtr) {
- error("Could not allocate memory for row pointers.");
- }
-
- // Initialize row pointers
- for (i = 0; i < height; i++)
- pRowPtr[i] = uncompressedDataPtr + i * pitch;
-
- // Read image data
- png_read_image(png_ptr, pRowPtr);
-
- // Free row pointer buffer
- delete[] pRowPtr;
- }
-
- // Read additional data at the end.
- png_read_end(png_ptr, NULL);
-
- // Destroy libpng structures
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-#else
- Common::MemoryReadStream *fileStr = new Common::MemoryReadStream(fileDataPtr, fileSize, DisposeAfterUse::NO);
- Graphics::PNG *png = new Graphics::PNG();
- if (!png->read(fileStr)) // the fileStr pointer, and thus pFileData will be deleted after this is done
- error("Error while reading PNG image");
-
- Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
- Graphics::Surface *pngSurface = png->getSurface(format);
-
- width = pngSurface->w;
- height = pngSurface->h;
- uncompressedDataPtr = new byte[pngSurface->pitch * pngSurface->h];
- memcpy(uncompressedDataPtr, (byte *)pngSurface->pixels, pngSurface->pitch * pngSurface->h);
- pngSurface->free();
-
- delete pngSurface;
- delete png;
-
-#endif
- // Signal success
- return true;
-}
-
-bool PNGLoader::decodeImage(const byte *fileDataPtr, uint fileSize, byte *&uncompressedDataPtr, int &width, int &height, int &pitch) {
- return doDecodeImage(fileDataPtr, fileSize, uncompressedDataPtr, width, height, pitch);
-}
-
-#ifndef USE_INTERNAL_PNG_DECODER
-bool PNGLoader::doImageProperties(const byte *fileDataPtr, uint fileSize, int &width, int &height) {
- // Check for valid PNG signature
- if (!doIsCorrectImageFormat(fileDataPtr, fileSize))
- return false;
-
- png_structp png_ptr = NULL;
- png_infop info_ptr = NULL;
-
- // Create both PNG structures
- png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
- if (!png_ptr) {
- error("Could not create libpng read struct.");
- }
-
- info_ptr = png_create_info_struct(png_ptr);
- if (!info_ptr) {
- error("Could not create libpng info struct.");
- }
-
- // Use alternative reading function
- const byte **ref = &fileDataPtr;
- png_set_read_fn(png_ptr, (void *)ref, png_user_read_data);
-
- // Read PNG Header
- png_read_info(png_ptr, info_ptr);
-
- // Read out PNG informations
- int bitDepth;
- int colorType;
- png_uint_32 w, h;
- png_get_IHDR(png_ptr, info_ptr, &w, &h, &bitDepth, &colorType, NULL, NULL, NULL);
-
- width = w;
- height = h;
-
- // Destroy libpng structures
- png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
-
- return true;
-
-}
-
-bool PNGLoader::imageProperties(const byte *fileDataPtr, uint fileSize, int &width, int &height) {
- return doImageProperties(fileDataPtr, fileSize, width, height);
-}
-
-#else
- // We don't need to read the image properties here...
-#endif
-
-
-} // End of namespace Sword25
diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp
index 23bf2623ad..a9c9de4f0c 100644
--- a/engines/sword25/gfx/image/renderedimage.cpp
+++ b/engines/sword25/gfx/image/renderedimage.cpp
@@ -35,21 +35,13 @@
#include "common/savefile.h"
#include "sword25/package/packagemanager.h"
-#include "sword25/gfx/image/pngloader.h"
+#include "sword25/gfx/image/imgloader.h"
#include "sword25/gfx/image/renderedimage.h"
#include "common/system.h"
namespace Sword25 {
-// Duplicated from kernel/persistenceservice.cpp
-static Common::String generateSavegameFilename(uint slotID) {
- char buffer[100];
- // NOTE: This is hardcoded to sword25
- snprintf(buffer, 100, "%s.%.3d", "sword25", slotID);
- return Common::String(buffer);
-}
-
// -----------------------------------------------------------------------------
// CONSTRUCTION / DESTRUCTION
// -----------------------------------------------------------------------------
@@ -74,8 +66,9 @@ static Common::String loadString(Common::SeekableReadStream &in, uint maxSize =
static byte *readSavegameThumbnail(const Common::String &filename, uint &fileSize, bool &isPNG) {
byte *pFileData;
Common::SaveFileManager *sfm = g_system->getSavefileManager();
- int slotNum = atoi(filename.c_str() + filename.size() - 3);
- Common::InSaveFile *file = sfm->openForLoading(generateSavegameFilename(slotNum));
+ Common::InSaveFile *file = sfm->openForLoading(lastPathComponent(filename, '/'));
+ if (!file)
+ error("Save file \"%s\" could not be loaded.", filename.c_str());
// Seek to the actual PNG image
loadString(*file); // Marker (BS25SAVEGAME)
@@ -100,30 +93,6 @@ static byte *readSavegameThumbnail(const Common::String &filename, uint &fileSiz
return pFileData;
}
-// TODO: Move this method into a more generic image loading class, together with the PNG reading code
-static bool decodeThumbnail(const byte *pFileData, uint fileSize, byte *&pUncompressedData, int &width, int &height, int &pitch) {
- const byte *src = pFileData + 4; // skip header
- width = READ_LE_UINT16(src); src += 2;
- height = READ_LE_UINT16(src); src += 2;
- src++; // version, ignored for now
- pitch = width * 4;
-
- uint32 totalSize = pitch * height;
- pUncompressedData = new byte[totalSize];
- uint32 *dst = (uint32 *)pUncompressedData; // treat as uint32, for pixelformat output
- const Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
- byte r, g, b;
-
- for (uint32 i = 0; i < totalSize / 4; i++) {
- r = *src++;
- g = *src++;
- b = *src++;
- *dst++ = format.RGBToColor(r, g, b);
- }
-
- return true;
-}
-
RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
_data(0),
_width(0),
@@ -152,21 +121,12 @@ RenderedImage::RenderedImage(const Common::String &filename, bool &result) :
return;
}
-#ifndef USE_INTERNAL_PNG_DECODER
- // Determine image properties
- if (!PNGLoader::imageProperties(pFileData, fileSize, _width, _height)) {
- error("Could not read image properties.");
- delete[] pFileData;
- return;
- }
-#endif
-
// Uncompress the image
int pitch;
if (isPNG)
- result = PNGLoader::decodeImage(pFileData, fileSize, _data, _width, _height, pitch);
+ result = ImgLoader::decodePNGImage(pFileData, fileSize, _data, _width, _height, pitch);
else
- result = decodeThumbnail(pFileData, fileSize, _data, _width, _height, pitch);
+ result = ImgLoader::decodeThumbnailImage(pFileData, fileSize, _data, _width, _height, pitch);
if (!result) {
error("Could not decode image.");
diff --git a/engines/sword25/gfx/image/swimage.cpp b/engines/sword25/gfx/image/swimage.cpp
index 92d47368b2..0b9cc11df2 100644
--- a/engines/sword25/gfx/image/swimage.cpp
+++ b/engines/sword25/gfx/image/swimage.cpp
@@ -30,7 +30,7 @@
*/
#include "sword25/package/packagemanager.h"
-#include "sword25/gfx/image/pngloader.h"
+#include "sword25/gfx/image/imgloader.h"
#include "sword25/gfx/image/swimage.h"
namespace Sword25 {
@@ -53,18 +53,10 @@ SWImage::SWImage(const Common::String &filename, bool &result) :
return;
}
-#ifndef USE_INTERNAL_PNG_DECODER
- // Determine image properties
- if (!PNGLoader::imageProperties(pFileData, fileSize, _width, _height)) {
- error("Could not read image properties.");
- return;
- }
-#endif
-
// Uncompress the image
int pitch;
byte *pUncompressedData;
- if (!PNGLoader::decodeImage(pFileData, fileSize, pUncompressedData, _width, _height, pitch)) {
+ if (!ImgLoader::decodePNGImage(pFileData, fileSize, pUncompressedData, _width, _height, pitch)) {
error("Could not decode image.");
return;
}
diff --git a/engines/sword25/gfx/panel.cpp b/engines/sword25/gfx/panel.cpp
index 34ab4876ea..6d5b2a623d 100644
--- a/engines/sword25/gfx/panel.cpp
+++ b/engines/sword25/gfx/panel.cpp
@@ -47,12 +47,12 @@ Panel::Panel(RenderObjectPtr<RenderObject> parentPtr, int width, int height, uin
_height = height;
if (_width < 0) {
- error("Tried to initialise a panel with an invalid width (%d).", _width);
+ error("Tried to initialize a panel with an invalid width (%d).", _width);
return;
}
if (_height < 0) {
- error("Tried to initialise a panel with an invalid height (%d).", _height);
+ error("Tried to initialize a panel with an invalid height (%d).", _height);
return;
}
diff --git a/engines/sword25/gfx/screenshot.cpp b/engines/sword25/gfx/screenshot.cpp
index 8306d9ce6f..4f9ba1d3c5 100644
--- a/engines/sword25/gfx/screenshot.cpp
+++ b/engines/sword25/gfx/screenshot.cpp
@@ -29,9 +29,6 @@
*
*/
-// Disable symbol overrides so that we can use png.h
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
-
#include "common/memstream.h"
#include "common/textconsole.h"
#include "sword25/gfx/screenshot.h"
@@ -53,6 +50,8 @@ bool Screenshot::saveToFile(Graphics::Surface *data, Common::WriteStream *stream
for (uint y = 0; y < data->h; y++) {
for (uint x = 0; x < data->w; x++) {
+ // This is only called by createThumbnail below, which
+ // provides a fake 'surface' with LE data in it.
uint32 srcPixel = READ_LE_UINT32(pSrc);
pSrc += sizeof(uint32);
stream->writeByte((srcPixel >> 16) & 0xff); // R
@@ -93,7 +92,7 @@ Common::SeekableReadStream *Screenshot::createThumbnail(Graphics::Surface *data)
for (int j = 0; j < 4; ++j) {
const uint32 *srcP = (const uint32 *)data->getBasePtr(x * 4, y * 4 + j + 50);
for (int i = 0; i < 4; ++i) {
- uint32 pixel = READ_LE_UINT32(srcP + i);
+ uint32 pixel = READ_UINT32(srcP + i);
alpha += (pixel >> 24);
red += (pixel >> 16) & 0xff;
green += (pixel >> 8) & 0xff;
diff --git a/engines/sword25/input/inputengine.h b/engines/sword25/input/inputengine.h
index a84c215076..f79890a9fd 100644
--- a/engines/sword25/input/inputengine.h
+++ b/engines/sword25/input/inputengine.h
@@ -172,7 +172,7 @@ public:
/// --------------------------------------------------------------
/**
- * Initialises the input engine
+ * Initializes the input engine
* @return Returns a true on success, otherwise false.
*/
bool init();
diff --git a/engines/sword25/kernel/kernel.cpp b/engines/sword25/kernel/kernel.cpp
index f45137ce02..d6388eee2b 100644
--- a/engines/sword25/kernel/kernel.cpp
+++ b/engines/sword25/kernel/kernel.cpp
@@ -63,7 +63,7 @@ Kernel::Kernel() :
// Create the resource manager
_resourceManager = new ResourceManager(this);
- // Initialise the script engine
+ // Initialize the script engine
_script = new LuaScriptEngine(this);
if (!_script || !_script->init()) {
_initSuccess = false;
diff --git a/engines/sword25/kernel/kernel.h b/engines/sword25/kernel/kernel.h
index a0c2927fdc..adf69f92d6 100644
--- a/engines/sword25/kernel/kernel.h
+++ b/engines/sword25/kernel/kernel.h
@@ -79,7 +79,7 @@ public:
uint getMilliTicks();
/**
- * Specifies whether the kernel was successfully initialised
+ * Specifies whether the kernel was successfully initialized
*/
bool getInitSuccess() const {
return _initSuccess;
diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp
index a6c71433a7..17e9199b5c 100644
--- a/engines/sword25/kernel/persistenceservice.cpp
+++ b/engines/sword25/kernel/persistenceservice.cpp
@@ -29,9 +29,6 @@
*
*/
-// Disable symbol overrides so that we can use zlib.h
-#define FORBIDDEN_SYMBOL_ALLOW_ALL
-
#include "common/fs.h"
#include "common/savefile.h"
#include "common/zlib.h"
@@ -304,6 +301,7 @@ bool PersistenceService::saveGame(uint slotID, const Common::String &screenshotF
if (thumbnail) {
byte *buffer = new byte[FILE_COPY_BUFFER_SIZE];
+ thumbnail->seek(0, SEEK_SET);
while (!thumbnail->eos()) {
int bytesRead = thumbnail->read(&buffer[0], FILE_COPY_BUFFER_SIZE);
file->write(&buffer[0], bytesRead);
diff --git a/engines/sword25/math/polygon.cpp b/engines/sword25/math/polygon.cpp
index fe2fc84cad..2e7836ff77 100644
--- a/engines/sword25/math/polygon.cpp
+++ b/engines/sword25/math/polygon.cpp
@@ -59,7 +59,7 @@ Polygon::~Polygon() {
}
bool Polygon::init(int vertexCount_, const Vertex *vertices_) {
- // Rember the old obstate to restore it if an error occurs whilst initialising it with the new data
+ // Rember the old obstate to restore it if an error occurs whilst initializing it with the new data
int oldvertexCount = this->vertexCount;
Vertex *oldvertices = this->vertices;
diff --git a/engines/sword25/math/polygon.h b/engines/sword25/math/polygon.h
index eac19d7900..ffdbf14f6b 100644
--- a/engines/sword25/math/polygon.h
+++ b/engines/sword25/math/polygon.h
@@ -78,15 +78,15 @@ public:
virtual ~Polygon();
/**
- * Initialises the BS_Polygon with a list of Vertecies.
+ * Initializes the BS_Polygon with a list of Vertecies.
*
* The Vertices need to define a polygon must not have self-intersections.
- * If a polygon already has verticies, this will re-initialise it with the new list.
+ * If a polygon already has verticies, this will re-initialize it with the new list.
*
* @param VertexCount The number of vertices being passed
* @param Vertecies An array of BS_Vertex objects representing the vertices in the polygon.
* @return Returns false if the Vertecies have self-intersections. In this case,
- * the object is not initialised.
+ * the object is not initialized.
*/
bool init(int vertexCount_, const Vertex *vertices_);
diff --git a/engines/sword25/math/region.cpp b/engines/sword25/math/region.cpp
index 8790860a55..7681ef6d9f 100644
--- a/engines/sword25/math/region.cpp
+++ b/engines/sword25/math/region.cpp
@@ -115,7 +115,7 @@ bool Region::init(const Polygon &contour, const Common::Array<Polygon> *pHoles)
}
- // Initialise bounding box
+ // Initialize bounding box
updateBoundingBox();
_valid = true;
diff --git a/engines/sword25/math/region.h b/engines/sword25/math/region.h
index f9a3f50b3f..0fd7223631 100644
--- a/engines/sword25/math/region.h
+++ b/engines/sword25/math/region.h
@@ -73,12 +73,12 @@ public:
virtual ~Region();
/**
- * Initialises a BS_Region object
+ * Initializes a BS_Region object
* @param Contour A polygon indicating the outline of the region
* @param pHoles A pointer to an array of polygons representing the hole state in the region.
* If the region has no holes, it must be passed as NULL. The default value is NULL.
* @return Returns true if the initialisation was successful, otherwise false.
- * @remark If the region was already initialised, the old state will be deleted.
+ * @remark If the region was already initialized, the old state will be deleted.
*/
virtual bool init(const Polygon &contour, const Common::Array<Polygon> *pHoles = NULL);
diff --git a/engines/sword25/math/vertex.h b/engines/sword25/math/vertex.h
index 817f48e760..4cb0eaca30 100644
--- a/engines/sword25/math/vertex.h
+++ b/engines/sword25/math/vertex.h
@@ -43,7 +43,8 @@
#include <math.h>
#include "common/rect.h"
#include "sword25/kernel/common.h"
-#include "sword25/util/lua/lua.h"
+
+struct lua_State;
#if defined(MACOSX) || defined(SOLARIS) || defined(__MINGW32__)
#define sqrtf(x) ((float)sqrt(x))
diff --git a/engines/sword25/math/walkregion.cpp b/engines/sword25/math/walkregion.cpp
index 3eea689877..bace4d54bc 100644
--- a/engines/sword25/math/walkregion.cpp
+++ b/engines/sword25/math/walkregion.cpp
@@ -101,7 +101,7 @@ static void initDijkstraNodes(DijkstraNode::Container &dijkstraNodes, const Regi
// Allocate sufficient space in the array
dijkstraNodes.resize(nodes.size());
- // Initialise all the nodes which are visible from the starting node
+ // Initialize all the nodes which are visible from the starting node
DijkstraNode::Iter dijkstraIter = dijkstraNodes.begin();
for (Common::Array<Vertex>::const_iterator nodesIter = nodes.begin();
nodesIter != nodes.end(); nodesIter++, dijkstraIter++) {
@@ -173,7 +173,7 @@ void reverseArray(Common::Array<T> &arr) {
bool WalkRegion::findPath(const Vertex &start, const Vertex &end, BS_Path &path) const {
// This is an implementation of Dijkstra's algorithm
- // Initialise edge node list
+ // Initialize edge node list
DijkstraNode::Container dijkstraNodes;
initDijkstraNodes(dijkstraNodes, *this, start, _nodes);
@@ -247,7 +247,7 @@ void WalkRegion::initNodeVector() {
}
void WalkRegion::computeVisibilityMatrix() {
- // Initialise visibility matrix
+ // Initialize visibility matrix
_visibilityMatrix = Common::Array< Common::Array <int> >();
for (uint idx = 0; idx < _nodes.size(); ++idx) {
Common::Array<int> arr;
diff --git a/engines/sword25/module.mk b/engines/sword25/module.mk
index da91c848b5..302120c500 100644
--- a/engines/sword25/module.mk
+++ b/engines/sword25/module.mk
@@ -24,7 +24,7 @@ MODULE_OBJS := \
gfx/text.o \
gfx/timedrenderobject.o \
gfx/image/art.o \
- gfx/image/pngloader.o \
+ gfx/image/imgloader.o \
gfx/image/renderedimage.o \
gfx/image/swimage.o \
gfx/image/vectorimage.o \
@@ -60,7 +60,6 @@ MODULE_OBJS := \
util/lua/ldblib.o \
util/lua/ldebug.o \
util/lua/ldo.o \
- util/lua/ldump.o \
util/lua/lfunc.o \
util/lua/lgc.o \
util/lua/linit.o \
@@ -79,10 +78,9 @@ MODULE_OBJS := \
util/lua/ltable.o \
util/lua/ltablib.o \
util/lua/ltm.o \
- util/lua/lundump.o \
util/lua/lvm.o \
util/lua/lzio.o \
- util/lua/print.o \
+ util/lua/scummvm_file.o \
util/pluto/pdep.o \
util/pluto/pluto.o \
util/pluto/plzio.o
diff --git a/engines/sword25/script/luascript.cpp b/engines/sword25/script/luascript.cpp
index 7fd3d1b658..9d394309e6 100644
--- a/engines/sword25/script/luascript.cpp
+++ b/engines/sword25/script/luascript.cpp
@@ -112,7 +112,7 @@ bool LuaScriptEngine::init() {
// Place the error handler function in the Lua registry, and remember the index
_pcallErrorhandlerRegistryIndex = luaL_ref(_state, LUA_REGISTRYINDEX);
- // Initialise the Pluto-Persistence library
+ // Initialize the Pluto-Persistence library
luaopen_pluto(_state);
lua_pop(_state, 1);
@@ -177,7 +177,7 @@ bool LuaScriptEngine::executeFile(const Common::String &fileName) {
}
bool LuaScriptEngine::executeString(const Common::String &code) {
- return executeBuffer((byte *)code.c_str(), code.size(), "???");
+ return executeBuffer((const byte *)code.c_str(), code.size(), "???");
}
namespace {
diff --git a/engines/sword25/script/luascript.h b/engines/sword25/script/luascript.h
index f3530d68ed..1a4a38c3be 100644
--- a/engines/sword25/script/luascript.h
+++ b/engines/sword25/script/luascript.h
@@ -36,7 +36,8 @@
#include "common/str-array.h"
#include "sword25/kernel/common.h"
#include "sword25/script/script.h"
-#include "sword25/util/lua/lua.h"
+
+struct lua_State;
namespace Sword25 {
@@ -48,7 +49,7 @@ public:
virtual ~LuaScriptEngine();
/**
- * Initialises the scripting engine
+ * Initializes the scripting engine
* @return Returns true if successful, otherwise false.
*/
virtual bool init();
diff --git a/engines/sword25/script/script.h b/engines/sword25/script/script.h
index e4ce846b66..04f248fe7e 100644
--- a/engines/sword25/script/script.h
+++ b/engines/sword25/script/script.h
@@ -54,7 +54,7 @@ public:
// -----------------------------------------------------------------------------
/**
- * Initialises the scrip tengine. Returns true if successful, false otherwise.
+ * Initializes the scrip tengine. Returns true if successful, false otherwise.
*/
virtual bool init() = 0;
diff --git a/engines/sword25/sfx/soundengine.h b/engines/sword25/sfx/soundengine.h
index c087392570..4dbd475846 100644
--- a/engines/sword25/sfx/soundengine.h
+++ b/engines/sword25/sfx/soundengine.h
@@ -88,7 +88,7 @@ public:
~SoundEngine() {}
/**
- * Initialises the sound engine
+ * Initializes the sound engine
* @param SampleRate Specifies the sample rate to use.
* @param Channels The maximum number of channels. The default is 32.
* @return Returns true on success, otherwise false.
diff --git a/engines/sword25/sword25.cpp b/engines/sword25/sword25.cpp
index 93666fed39..b111746c32 100644
--- a/engines/sword25/sword25.cpp
+++ b/engines/sword25/sword25.cpp
@@ -94,7 +94,7 @@ Common::Error Sword25Engine::run() {
}
Common::Error Sword25Engine::appStart() {
- // Initialise the graphics mode to ARGB8888
+ // Initialize the graphics mode to ARGB8888
Graphics::PixelFormat format = Graphics::PixelFormat(4, 8, 8, 8, 8, 16, 8, 0, 24);
initGraphics(800, 600, true, &format);
if (format != g_system->getScreenFormat())
@@ -142,7 +142,7 @@ bool Sword25Engine::appMain() {
}
bool Sword25Engine::appEnd() {
- // The kernel is shutdown, and un-initialises all subsystems
+ // The kernel is shutdown, and un-initializes all subsystems
Kernel::deleteInstance();
AnimationTemplateRegistry::destroy();
diff --git a/engines/sword25/sword25.h b/engines/sword25/sword25.h
index 5d11aa69e5..1254ea177b 100644
--- a/engines/sword25/sword25.h
+++ b/engines/sword25/sword25.h
@@ -82,7 +82,7 @@ protected:
// void pauseEngineIntern(bool pause); // TODO: Implement this!!!
// void syncSoundSettings(); // TODO: Implement this!!!
// Common::Error loadGameState(int slot); // TODO: Implement this?
-// Common::Error saveGameState(int slot, const char *desc); // TODO: Implement this?
+// Common::Error saveGameState(int slot, const Common::String &desc); // TODO: Implement this?
// bool canLoadGameStateCurrently(); // TODO: Implement this?
// bool canSaveGameStateCurrently(); // TODO: Implement this?
diff --git a/engines/sword25/util/lua/lapi.cpp b/engines/sword25/util/lua/lapi.cpp
index b1118db368..16f8460e39 100644
--- a/engines/sword25/util/lua/lapi.cpp
+++ b/engines/sword25/util/lua/lapi.cpp
@@ -26,9 +26,8 @@
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
-#include "lundump.h"
#include "lvm.h"
-
+#include "common/textconsole.h"
const char lua_ident[] =
@@ -876,17 +875,8 @@ LUA_API int lua_load (lua_State *L, lua_Reader reader, void *data,
LUA_API int lua_dump (lua_State *L, lua_Writer writer, void *data) {
- int status;
- TValue *o;
- lua_lock(L);
- api_checknelems(L, 1);
- o = L->top - 1;
- if (isLfunction(o))
- status = luaU_dump(L, clvalue(o)->l.p, writer, data, 0);
- else
- status = 1;
- lua_unlock(L);
- return status;
+ error("lua_dump not supported: Handling of precompiled LUA scripts has been removed in ScummVM");
+ return 1; // error
}
diff --git a/engines/sword25/util/lua/lauxlib.cpp b/engines/sword25/util/lua/lauxlib.cpp
index 526b1c84ab..8978cd5613 100644
--- a/engines/sword25/util/lua/lauxlib.cpp
+++ b/engines/sword25/util/lua/lauxlib.cpp
@@ -22,7 +22,8 @@
#include "lua.h"
#include "lauxlib.h"
-
+#include "scummvm_file.h"
+#include "common/textconsole.h"
#define FREELIST_REF 0 /* free list of references */
@@ -520,7 +521,7 @@ LUALIB_API void luaL_unref (lua_State *L, int t, int ref) {
typedef struct LoadF {
int extraline;
- FILE *f;
+ Sword25::Sword25FileProxy *f;
char buff[LUAL_BUFFERSIZE];
} LoadF;
@@ -533,23 +534,31 @@ static const char *getF (lua_State *L, void *ud, size_t *size) {
*size = 1;
return "\n";
}
- if (feof(lf->f)) return NULL;
- *size = fread(lf->buff, 1, sizeof(lf->buff), lf->f);
+ if (lf->f->eof()) return NULL;
+ *size = lf->f->read(lf->buff, 1, sizeof(lf->buff));
return (*size > 0) ? lf->buff : NULL;
}
static int errfile (lua_State *L, const char *what, int fnameindex) {
- return luaL_error(L, "LUA function errfile has been removed in ScummVM");
+ const char *serr = "General error";
+ const char *filename = lua_tostring(L, fnameindex) + 1;
+ lua_pushfstring(L, "cannot %s %s: %s", what, filename, serr);
+ lua_remove(L, fnameindex);
+ return LUA_ERRFILE;
}
LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
LoadF lf;
int status, readstatus;
- int c;
+// int c;
int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
lf.extraline = 0;
+
+ lua_pushfstring(L, "@%s", filename);
+ lf.f = new Sword25::Sword25FileProxy(filename, "r");
+/*
if (filename == NULL) {
lua_pushliteral(L, "=stdin");
lf.f = stdin;
@@ -559,23 +568,25 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) {
lf.f = fopen(filename, "r");
if (lf.f == NULL) return errfile(L, "open", fnameindex);
}
- c = getc(lf.f);
- if (c == '#') { /* Unix exec. file? */
+
+ c = lf.f->getc();
+ if (c == '#') { // Unix exec. file?
lf.extraline = 1;
- while ((c = getc(lf.f)) != EOF && c != '\n') ; /* skip first line */
- if (c == '\n') c = getc(lf.f);
+ while ((c = lf.f->getc()) != EOF && c != '\n') ; // skip first line
+ if (c == '\n') c = lf.f->getc();
}
- if (c == LUA_SIGNATURE[0] && filename) { /* binary file? */
- lf.f = freopen(filename, "rb", lf.f); /* reopen in binary mode */
+ if (c == LUA_SIGNATURE[0] && filename) { // binary file?
+ lf.f = freopen(filename, "rb", lf.f); // reopen in binary mode
if (lf.f == NULL) return errfile(L, "reopen", fnameindex);
- /* skip eventual `#!...' */
- while ((c = getc(lf.f)) != EOF && c != LUA_SIGNATURE[0]) ;
+ // skip eventual `#!...'
+ while ((c = lf.f->getc()) != EOF && c != LUA_SIGNATURE[0]) ;
lf.extraline = 0;
}
ungetc(c, lf.f);
+*/
status = lua_load(L, getF, &lf, lua_tostring(L, -1));
- readstatus = ferror(lf.f);
- if (filename) fclose(lf.f); /* close file (even in case of errors) */
+ readstatus = 0; //ferror(lf.f);
+ if (filename) delete lf.f; // close file (even in case of errors)
if (readstatus) {
lua_settop(L, fnameindex); /* ignore results from `lua_load' */
return errfile(L, "read", fnameindex);
@@ -633,7 +644,7 @@ static void *l_alloc (void *ud, void *ptr, size_t osize, size_t nsize) {
static int panic (lua_State *L) {
(void)L; /* to avoid warnings */
- fprintf(stderr, "PANIC: unprotected error in call to Lua API (%s)\n",
+ warning("PANIC: unprotected error in call to Lua API (%s)\n",
lua_tostring(L, -1));
return 0;
}
diff --git a/engines/sword25/util/lua/ldo.cpp b/engines/sword25/util/lua/ldo.cpp
index 07508fbb14..bbcdf98b3d 100644
--- a/engines/sword25/util/lua/ldo.cpp
+++ b/engines/sword25/util/lua/ldo.cpp
@@ -5,6 +5,16 @@
*/
+// FIXME: LUAI_THROW and LUAI_TRY use either throw/catch or setjmp/longjmp.
+// Neither of these is supported in ScummVM. So we need to come up
+// with a replacement. The most simple, direct and crude approach:
+// Replace "throw" with an "error()" call. Of course we only
+// would want to do that if this actually never happens...
+#define FORBIDDEN_SYMBOL_EXCEPTION_setjmp
+#define FORBIDDEN_SYMBOL_EXCEPTION_longjmp
+
+#include "common/textconsole.h"
+
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
@@ -26,10 +36,9 @@
#include "lstring.h"
#include "ltable.h"
#include "ltm.h"
-#include "lundump.h"
#include "lvm.h"
#include "lzio.h"
-
+#include "common/textconsole.h"
@@ -94,6 +103,11 @@ static void resetstack (lua_State *L, int status) {
void luaD_throw (lua_State *L, int errcode) {
if (L->errorJmp) {
L->errorJmp->status = errcode;
+ // FIXME: LUAI_THROW and LUAI_TRY use either throw/catch or setjmp/longjmp.
+ // Neither of these is supported in ScummVM. So we need to come up
+ // with a replacement. The most simple, direct and crude approach:
+ // Replace "throw" with an "error()" call. Of course we only
+ // would want to do that if this actually never happens...
LUAI_THROW(L, L->errorJmp);
}
else {
@@ -103,7 +117,7 @@ void luaD_throw (lua_State *L, int errcode) {
lua_unlock(L);
G(L)->panic(L);
}
- exit(EXIT_FAILURE);
+ error("luaD_throw failure");
}
}
@@ -113,6 +127,11 @@ int luaD_rawrunprotected (lua_State *L, Pfunc f, void *ud) {
lj.status = 0;
lj.previous = L->errorJmp; /* chain new error handler */
L->errorJmp = &lj;
+ // FIXME: LUAI_THROW and LUAI_TRY use either throw/catch or setjmp/longjmp.
+ // Neither of these is supported in ScummVM. So we need to come up
+ // with a replacement. The most simple, direct and crude approach:
+ // Replace "throw" with an "error()" call. Of course we only
+ // would want to do that if this actually never happens...
LUAI_TRY(L, &lj,
(*f)(L, ud);
);
@@ -494,8 +513,9 @@ static void f_parser (lua_State *L, void *ud) {
struct SParser *p = cast(struct SParser *, ud);
int c = luaZ_lookahead(p->z);
luaC_checkGC(L);
- tf = ((c == LUA_SIGNATURE[0]) ? luaU_undump : luaY_parser)(L, p->z,
- &p->buff, p->name);
+ if (c == LUA_SIGNATURE[0])
+ error("Handling of precompiled LUA scripts has been removed in ScummVM");
+ tf = luaY_parser(L, p->z, &p->buff, p->name);
cl = luaF_newLclosure(L, tf->nups, hvalue(gt(L)));
cl->l.p = tf;
for (i = 0; i < tf->nups; i++) /* initialize eventual upvalues */
diff --git a/engines/sword25/util/lua/ldump.cpp b/engines/sword25/util/lua/ldump.cpp
deleted file mode 100644
index 3ce16542d6..0000000000
--- a/engines/sword25/util/lua/ldump.cpp
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
-** $Id$
-** save precompiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#include <stddef.h>
-
-#define ldump_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "lobject.h"
-#include "lstate.h"
-#include "lundump.h"
-
-typedef struct {
- lua_State* L;
- lua_Writer writer;
- void* data;
- int strip;
- int status;
-} DumpState;
-
-#define DumpMem(b,n,size,D) DumpBlock(b,(n)*(size),D)
-#define DumpVar(x,D) DumpMem(&x,1,sizeof(x),D)
-
-static void DumpBlock(const void* b, size_t size, DumpState* D)
-{
- if (D->status==0)
- {
- lua_unlock(D->L);
- D->status=(*D->writer)(D->L,b,size,D->data);
- lua_lock(D->L);
- }
-}
-
-static void DumpChar(int y, DumpState* D)
-{
- char x=(char)y;
- DumpVar(x,D);
-}
-
-static void DumpInt(int x, DumpState* D)
-{
- DumpVar(x,D);
-}
-
-static void DumpNumber(lua_Number x, DumpState* D)
-{
- DumpVar(x,D);
-}
-
-static void DumpVector(const void* b, int n, size_t size, DumpState* D)
-{
- DumpInt(n,D);
- DumpMem(b,n,size,D);
-}
-
-static void DumpString(const TString* s, DumpState* D)
-{
- if (s==NULL || getstr(s)==NULL)
- {
- size_t size=0;
- DumpVar(size,D);
- }
- else
- {
- size_t size=s->tsv.len+1; /* include trailing '\0' */
- DumpVar(size,D);
- DumpBlock(getstr(s),size,D);
- }
-}
-
-#define DumpCode(f,D) DumpVector(f->code,f->sizecode,sizeof(Instruction),D)
-
-static void DumpFunction(const Proto* f, const TString* p, DumpState* D);
-
-static void DumpConstants(const Proto* f, DumpState* D)
-{
- int i,n=f->sizek;
- DumpInt(n,D);
- for (i=0; i<n; i++)
- {
- const TValue* o=&f->k[i];
- DumpChar(ttype(o),D);
- switch (ttype(o))
- {
- case LUA_TNIL:
- break;
- case LUA_TBOOLEAN:
- DumpChar(bvalue(o),D);
- break;
- case LUA_TNUMBER:
- DumpNumber(nvalue(o),D);
- break;
- case LUA_TSTRING:
- DumpString(rawtsvalue(o),D);
- break;
- default:
- lua_assert(0); /* cannot happen */
- break;
- }
- }
- n=f->sizep;
- DumpInt(n,D);
- for (i=0; i<n; i++) DumpFunction(f->p[i],f->source,D);
-}
-
-static void DumpDebug(const Proto* f, DumpState* D)
-{
- int i,n;
- n= (D->strip) ? 0 : f->sizelineinfo;
- DumpVector(f->lineinfo,n,sizeof(int),D);
- n= (D->strip) ? 0 : f->sizelocvars;
- DumpInt(n,D);
- for (i=0; i<n; i++)
- {
- DumpString(f->locvars[i].varname,D);
- DumpInt(f->locvars[i].startpc,D);
- DumpInt(f->locvars[i].endpc,D);
- }
- n= (D->strip) ? 0 : f->sizeupvalues;
- DumpInt(n,D);
- for (i=0; i<n; i++) DumpString(f->upvalues[i],D);
-}
-
-static void DumpFunction(const Proto* f, const TString* p, DumpState* D)
-{
- DumpString((f->source==p || D->strip) ? NULL : f->source,D);
- DumpInt(f->linedefined,D);
- DumpInt(f->lastlinedefined,D);
- DumpChar(f->nups,D);
- DumpChar(f->numparams,D);
- DumpChar(f->is_vararg,D);
- DumpChar(f->maxstacksize,D);
- DumpCode(f,D);
- DumpConstants(f,D);
- DumpDebug(f,D);
-}
-
-static void DumpHeader(DumpState* D)
-{
- char h[LUAC_HEADERSIZE];
- luaU_header(h);
- DumpBlock(h,LUAC_HEADERSIZE,D);
-}
-
-/*
-** dump Lua function as precompiled chunk
-*/
-int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip)
-{
- DumpState D;
- D.L=L;
- D.writer=w;
- D.data=data;
- D.strip=strip;
- D.status=0;
- DumpHeader(&D);
- DumpFunction(f,NULL,&D);
- return D.status;
-}
diff --git a/engines/sword25/util/lua/liolib.cpp b/engines/sword25/util/lua/liolib.cpp
index f9bad30aed..b505d1e4df 100644
--- a/engines/sword25/util/lua/liolib.cpp
+++ b/engines/sword25/util/lua/liolib.cpp
@@ -16,7 +16,8 @@
#include "lauxlib.h"
#include "lualib.h"
-
+#include "common/textconsole.h"
+#include "scummvm_file.h"
#define IO_INPUT 1
@@ -27,50 +28,64 @@ static const char *const fnames[] = {"input", "output"};
static int pushresult (lua_State *L, int i, const char *filename) {
- return luaL_error(L, "LUA file I/O functions have been removed in ScummVM");
+ int en = 0; /*errno;*/ // Currently hardcoded for ScumMVM, this may need to be changed
+ if (i) {
+ lua_pushboolean(L, 1);
+ return 1;
+ }
+ else {
+ lua_pushnil(L);
+ if (filename)
+ lua_pushfstring(L, "%s: %s", filename, "General error" /*strerror(en)*/);
+ else
+ lua_pushfstring(L, "%s", "General error" /*strerror(en)*/);
+ lua_pushinteger(L, en);
+ return 3;
+ }
}
-
+/*
static void fileerror (lua_State *L, int arg, const char *filename) {
lua_pushfstring(L, "%s: %s", filename, "LUA I/O error descriptions have been removed in ScummVM");
luaL_argerror(L, arg, lua_tostring(L, -1));
}
-
+*/
#define tofilep(L) ((FILE **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
-
+#define tofileProxy(L) ((Sword25::Sword25FileProxy **)luaL_checkudata(L, 1, LUA_FILEHANDLE))
static int io_type (lua_State *L) {
+ return luaL_error(L, "%s", "LUA I/O has been removed in ScummVM");
+/*
void *ud;
luaL_checkany(L, 1);
ud = lua_touserdata(L, 1);
lua_getfield(L, LUA_REGISTRYINDEX, LUA_FILEHANDLE);
if (ud == NULL || !lua_getmetatable(L, 1) || !lua_rawequal(L, -2, -1))
- lua_pushnil(L); /* not a file */
+ lua_pushnil(L); // not a file
else if (*((FILE **)ud) == NULL)
lua_pushliteral(L, "closed file");
else
lua_pushliteral(L, "file");
return 1;
+*/
}
-
-static FILE *tofile (lua_State *L) {
- FILE **f = tofilep(L);
+static Sword25::Sword25FileProxy *tofile (lua_State *L) {
+ Sword25::Sword25FileProxy **f = tofileProxy(L);
if (*f == NULL)
luaL_error(L, "attempt to use a closed file");
return *f;
}
-
/*
** When creating file handles, always creates a `closed' file handle
** before opening the actual file; so, if there is a memory error, the
** file is not left opened.
*/
-static FILE **newfile (lua_State *L) {
- FILE **pf = (FILE **)lua_newuserdata(L, sizeof(FILE *));
+static Sword25::Sword25FileProxy **newfile (lua_State *L) {
+ Sword25::Sword25FileProxy **pf = (Sword25::Sword25FileProxy **)lua_newuserdata(L, sizeof(Sword25::Sword25FileProxy *));
*pf = NULL; /* file handle is currently `closed' */
luaL_getmetatable(L, LUA_FILEHANDLE);
lua_setmetatable(L, -2);
@@ -92,10 +107,13 @@ static int io_noclose (lua_State *L) {
** function to close 'popen' files
*/
static int io_pclose (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+/*
FILE **p = tofilep(L);
int ok = lua_pclose(L, *p);
*p = NULL;
return pushresult(L, ok, NULL);
+ */
}
@@ -103,52 +121,63 @@ static int io_pclose (lua_State *L) {
** function to close regular files
*/
static int io_fclose (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+ /*
FILE **p = tofilep(L);
int ok = (fclose(*p) == 0);
*p = NULL;
return pushresult(L, ok, NULL);
+ */
}
-
+/*
static int aux_close (lua_State *L) {
lua_getfenv(L, 1);
lua_getfield(L, -1, "__close");
return (lua_tocfunction(L, -1))(L);
}
-
+*/
static int io_close (lua_State *L) {
if (lua_isnone(L, 1))
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_OUTPUT);
- tofile(L); /* make sure argument is a file */
- return aux_close(L);
+
+ Sword25::Sword25FileProxy **f = tofileProxy(L);
+ delete *f;
+ *f = NULL;
+
+ return 0;
}
static int io_gc (lua_State *L) {
- FILE *f = *tofilep(L);
- /* ignore closed files */
- if (f != NULL)
- aux_close(L);
+ Sword25::Sword25FileProxy **f = tofileProxy(L);
+ // ignore closed files
+ if (*f != NULL)
+ delete *f;
+
return 0;
}
static int io_tostring (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+ /*
FILE *f = *tofilep(L);
if (f == NULL)
lua_pushliteral(L, "file (closed)");
else
lua_pushfstring(L, "file (%p)", f);
return 1;
+ */
}
static int io_open (lua_State *L) {
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
- FILE **pf = newfile(L);
- *pf = fopen(filename, mode);
+ Sword25::Sword25FileProxy **pf = newfile(L);
+ *pf = new Sword25::Sword25FileProxy(filename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
}
@@ -158,21 +187,22 @@ static int io_open (lua_State *L) {
** correct __close for 'popen' files
*/
static int io_popen (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+/*
const char *filename = luaL_checkstring(L, 1);
const char *mode = luaL_optstring(L, 2, "r");
FILE **pf = newfile(L);
*pf = lua_popen(L, filename, mode);
return (*pf == NULL) ? pushresult(L, 0, filename) : 1;
+ */
}
static int io_tmpfile (lua_State *L) {
- FILE **pf = newfile(L);
- *pf = tmpfile();
- return (*pf == NULL) ? pushresult(L, 0, NULL) : 1;
+ return luaL_error(L, "%s", "LUA I/O error descriptions have been removed in ScummVM");
}
-
+/*
static FILE *getiofile (lua_State *L, int findex) {
FILE *f;
lua_rawgeti(L, LUA_ENVIRONINDEX, findex);
@@ -181,8 +211,8 @@ static FILE *getiofile (lua_State *L, int findex) {
luaL_error(L, "standard %s file is closed", fnames[findex - 1]);
return f;
}
-
-
+*/
+/*
static int g_iofile (lua_State *L, int f, const char *mode) {
if (!lua_isnoneornil(L, 1)) {
const char *filename = lua_tostring(L, 1);
@@ -193,24 +223,26 @@ static int g_iofile (lua_State *L, int f, const char *mode) {
fileerror(L, 1, filename);
}
else {
- tofile(L); /* check that it's a valid file handle */
+ tofile(L); // check that it's a valid file handle
lua_pushvalue(L, 1);
}
lua_rawseti(L, LUA_ENVIRONINDEX, f);
}
- /* return current value */
+ // return current value
lua_rawgeti(L, LUA_ENVIRONINDEX, f);
return 1;
}
-
+*/
static int io_input (lua_State *L) {
- return g_iofile(L, IO_INPUT, "r");
+ error("LUA I/O has been removed in ScummVM");
+// return g_iofile(L, IO_INPUT, "r");
}
static int io_output (lua_State *L) {
- return g_iofile(L, IO_OUTPUT, "w");
+ error("LUA I/O has been removed in ScummVM");
+// return g_iofile(L, IO_OUTPUT, "w");
}
@@ -232,8 +264,10 @@ static int f_lines (lua_State *L) {
static int io_lines (lua_State *L) {
- if (lua_isnoneornil(L, 1)) { /* no arguments? */
- /* will iterate over default input */
+ error("LUA I/O has been removed in ScummVM");
+/*
+ if (lua_isnoneornil(L, 1)) { // no arguments?
+ // will iterate over default input
lua_rawgeti(L, LUA_ENVIRONINDEX, IO_INPUT);
return f_lines(L);
}
@@ -246,6 +280,7 @@ static int io_lines (lua_State *L) {
aux_lines(L, lua_gettop(L), 1);
return 1;
}
+ */
}
@@ -255,18 +290,18 @@ static int io_lines (lua_State *L) {
** =======================================================
*/
-
-static int read_number (lua_State *L, FILE *f) {
+/*
+static int read_number (lua_State *L, Sword25::Sword25FileProxy *f) {
lua_Number d;
if (fscanf(f, LUA_NUMBER_SCAN, &d) == 1) {
lua_pushnumber(L, d);
return 1;
}
- else return 0; /* read fails */
+ else return 0; // read fails
}
-static int test_eof (lua_State *L, FILE *f) {
+static int test_eof (lua_State *L, Sword25::Sword25FileProxy *f) {
int c = getc(f);
ungetc(c, f);
lua_pushlstring(L, NULL, 0);
@@ -274,56 +309,56 @@ static int test_eof (lua_State *L, FILE *f) {
}
-static int read_line (lua_State *L, FILE *f) {
+static int read_line (lua_State *L, Sword25::Sword25FileProxy *f) {
luaL_Buffer b;
luaL_buffinit(L, &b);
for (;;) {
size_t l;
char *p = luaL_prepbuffer(&b);
- if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { /* eof? */
- luaL_pushresult(&b); /* close buffer */
- return (lua_objlen(L, -1) > 0); /* check whether read something */
+ if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { // eof?
+ luaL_pushresult(&b); // close buffer
+ return (lua_objlen(L, -1) > 0); // check whether read something
}
l = strlen(p);
if (l == 0 || p[l-1] != '\n')
luaL_addsize(&b, l);
else {
- luaL_addsize(&b, l - 1); /* do not include `eol' */
- luaL_pushresult(&b); /* close buffer */
- return 1; /* read at least an `eol' */
+ luaL_addsize(&b, l - 1); // do not include `eol'
+ luaL_pushresult(&b); // close buffer
+ return 1; // read at least an `eol'
}
}
}
-static int read_chars (lua_State *L, FILE *f, size_t n) {
- size_t rlen; /* how much to read */
- size_t nr; /* number of chars actually read */
+static int read_chars (lua_State *L, Sword25::Sword25FileProxy *f, size_t n) {
+ size_t rlen; // how much to read
+ size_t nr; // number of chars actually read
luaL_Buffer b;
luaL_buffinit(L, &b);
- rlen = LUAL_BUFFERSIZE; /* try to read that much each time */
+ rlen = LUAL_BUFFERSIZE; // try to read that much each time
do {
char *p = luaL_prepbuffer(&b);
- if (rlen > n) rlen = n; /* cannot read more than asked */
+ if (rlen > n) rlen = n; // cannot read more than asked
nr = fread(p, sizeof(char), rlen, f);
luaL_addsize(&b, nr);
- n -= nr; /* still have to read `n' chars */
- } while (n > 0 && nr == rlen); /* until end of count or eof */
- luaL_pushresult(&b); /* close buffer */
+ n -= nr; // still have to read `n' chars
+ } while (n > 0 && nr == rlen); // until end of count or eof
+ luaL_pushresult(&b); // close buffer
return (n == 0 || lua_objlen(L, -1) > 0);
}
-static int g_read (lua_State *L, FILE *f, int first) {
+static int g_read (lua_State *L, Sword25::Sword25FileProxy *f, int first) {
int nargs = lua_gettop(L) - 1;
int success;
int n;
clearerr(f);
- if (nargs == 0) { /* no arguments? */
+ if (nargs == 0) { // no arguments?
success = read_line(L, f);
- n = first+1; /* to return 1 result */
+ n = first+1; // to return 1 result
}
- else { /* ensure stack space for all results and for auxlib's buffer */
+ else { // ensure stack space for all results and for auxlib's buffer
luaL_checkstack(L, nargs+LUA_MINSTACK, "too many arguments");
success = 1;
for (n = first; nargs-- && success; n++) {
@@ -335,15 +370,15 @@ static int g_read (lua_State *L, FILE *f, int first) {
const char *p = lua_tostring(L, n);
luaL_argcheck(L, p && p[0] == '*', n, "invalid option");
switch (p[1]) {
- case 'n': /* number */
+ case 'n': // number
success = read_number(L, f);
break;
- case 'l': /* line */
+ case 'l': // line
success = read_line(L, f);
break;
- case 'a': /* file */
- read_chars(L, f, ~((size_t)0)); /* read MAX_SIZE_T chars */
- success = 1; /* always success */
+ case 'a': // file
+ read_chars(L, f, ~((size_t)0)); // read MAX_SIZE_T chars
+ success = 1; // always success
break;
default:
return luaL_argerror(L, n, "invalid format");
@@ -354,58 +389,66 @@ static int g_read (lua_State *L, FILE *f, int first) {
if (ferror(f))
return pushresult(L, 0, NULL);
if (!success) {
- lua_pop(L, 1); /* remove last result */
- lua_pushnil(L); /* push nil instead */
+ lua_pop(L, 1); // remove last result
+ lua_pushnil(L); // push nil instead
}
return n - first;
}
-
+*/
static int io_read (lua_State *L) {
- return g_read(L, getiofile(L, IO_INPUT), 1);
+ error("LUA I/O has been removed in ScummVM");
+// return g_read(L, getiofile(L, IO_INPUT), 1);
}
static int f_read (lua_State *L) {
- return g_read(L, tofile(L), 2);
+ error("LUA I/O has been removed in ScummVM");
+// return g_read(L, tofile(L), 2);
}
static int io_readline (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+/*
FILE *f = *(FILE **)lua_touserdata(L, lua_upvalueindex(1));
int sucess;
- if (f == NULL) /* file is already closed? */
+ if (f == NULL) // file is already closed?
luaL_error(L, "file is already closed");
sucess = read_line(L, f);
if (ferror(f))
return luaL_error(L, "%s", "LUA I/O error descriptions have been removed in ScummVM");
if (sucess) return 1;
- else { /* EOF */
- if (lua_toboolean(L, lua_upvalueindex(2))) { /* generator created file? */
+ else { // EOF
+ if (lua_toboolean(L, lua_upvalueindex(2))) { // generator created file?
lua_settop(L, 0);
lua_pushvalue(L, lua_upvalueindex(1));
- aux_close(L); /* close it */
+ aux_close(L); // close it
}
return 0;
}
+*/
}
/* }====================================================== */
-static int g_write (lua_State *L, FILE *f, int arg) {
+static int g_write (lua_State *L, Sword25::Sword25FileProxy *f, int arg) {
int nargs = lua_gettop(L) - 1;
int status = 1;
for (; nargs--; arg++) {
if (lua_type(L, arg) == LUA_TNUMBER) {
- /* optimization: could be done exactly as for strings */
- status = status &&
- fprintf(f, LUA_NUMBER_FMT, lua_tonumber(L, arg)) > 0;
- }
+ // optimization: could be done exactly as for strings
+ if (status) {
+ char buffer[20];
+ sprintf(buffer, LUA_NUMBER_FMT, lua_tonumber(L, arg));
+ status = f->write(buffer, strlen(buffer)) == strlen(buffer);
+ }
+ }
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
- status = status && (fwrite(s, sizeof(char), l, f) == l);
+ status = status && (f->write(s, l) == l);
}
}
return pushresult(L, status, NULL);
@@ -413,7 +456,8 @@ static int g_write (lua_State *L, FILE *f, int arg) {
static int io_write (lua_State *L) {
- return g_write(L, getiofile(L, IO_OUTPUT), 1);
+ error("LUA I/O has been removed in ScummVM");
+// return g_write(L, getiofile(L, IO_OUTPUT), 1);
}
@@ -423,6 +467,8 @@ static int f_write (lua_State *L) {
static int f_seek (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+ /*
static const int mode[] = {SEEK_SET, SEEK_CUR, SEEK_END};
static const char *const modenames[] = {"set", "cur", "end", NULL};
FILE *f = tofile(L);
@@ -430,15 +476,18 @@ static int f_seek (lua_State *L) {
long offset = luaL_optlong(L, 3, 0);
op = fseek(f, offset, mode[op]);
if (op)
- return pushresult(L, 0, NULL); /* error */
+ return pushresult(L, 0, NULL); // error
else {
lua_pushinteger(L, ftell(f));
return 1;
}
+*/
}
static int f_setvbuf (lua_State *L) {
+ error("LUA I/O has been removed in ScummVM");
+ /*
static const int mode[] = {_IONBF, _IOFBF, _IOLBF};
static const char *const modenames[] = {"no", "full", "line", NULL};
FILE *f = tofile(L);
@@ -446,17 +495,20 @@ static int f_setvbuf (lua_State *L) {
lua_Integer sz = luaL_optinteger(L, 3, LUAL_BUFFERSIZE);
int res = setvbuf(f, NULL, mode[op], sz);
return pushresult(L, res == 0, NULL);
+ */
}
static int io_flush (lua_State *L) {
- return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
+ error("LUA I/O has been removed in ScummVM");
+// return pushresult(L, fflush(getiofile(L, IO_OUTPUT)) == 0, NULL);
}
static int f_flush (lua_State *L) {
- return pushresult(L, fflush(tofile(L)) == 0, NULL);
+ error("LUA I/O has been removed in ScummVM");
+// return pushresult(L, fflush(tofile(L)) == 0, NULL);
}
@@ -497,18 +549,18 @@ static void createmeta (lua_State *L) {
luaL_register(L, NULL, flib); /* file methods */
}
-
+/*
static void createstdfile (lua_State *L, FILE *f, int k, const char *fname) {
*newfile(L) = f;
if (k > 0) {
lua_pushvalue(L, -1);
lua_rawseti(L, LUA_ENVIRONINDEX, k);
}
- lua_pushvalue(L, -2); /* copy environment */
- lua_setfenv(L, -2); /* set it */
+ lua_pushvalue(L, -2); // copy environment
+ lua_setfenv(L, -2); // set it
lua_setfield(L, -3, fname);
}
-
+*/
static void newfenv (lua_State *L, lua_CFunction cls) {
lua_createtable(L, 0, 1);
@@ -526,9 +578,11 @@ LUALIB_API int luaopen_io (lua_State *L) {
luaL_register(L, LUA_IOLIBNAME, iolib);
/* create (and set) default files */
newfenv(L, io_noclose); /* close function for default files */
+/*
createstdfile(L, stdin, IO_INPUT, "stdin");
createstdfile(L, stdout, IO_OUTPUT, "stdout");
createstdfile(L, stderr, 0, "stderr");
+*/
lua_pop(L, 1); /* pop environment for default files */
lua_getfield(L, -1, "popen");
newfenv(L, io_pclose); /* create environment for 'popen' */
diff --git a/engines/sword25/util/lua/llex.cpp b/engines/sword25/util/lua/llex.cpp
index 87eafea45a..4d73a6a600 100644
--- a/engines/sword25/util/lua/llex.cpp
+++ b/engines/sword25/util/lua/llex.cpp
@@ -6,6 +6,7 @@
#include <ctype.h>
+#include <stdio.h>
#include <string.h>
#define llex_c
@@ -175,11 +176,23 @@ static void buffreplace (LexState *ls, char from, char to) {
static void trydecpoint (LexState *ls, SemInfo *seminfo) {
/* format error: try to update decimal point separator */
- // Non-portable call to update the decimal point separator.
- // It has been simplified in ScummVM to not use any system locale
- // information, as it's not used in sword25.
+ // Normally we'd use localeconv() to get the decimal point separator, but
+ // annoyingly that is not available on some platforms, e.g. Android. Figure
+ // it out by formatting a known value and extract the separator from that
+ // instead. The result could be cached, but considering the game I doubt
+ // this will ever be a bottleneck. Note that the separator is assumed to fit
+ // in a char, but that was a limitation in the original code as well.
char old = ls->decpoint;
+ char buf[5];
+ int i;
+ sprintf(buf, "%.1f", 1.0);
ls->decpoint = '.';
+ for (i = 0; buf[i]; i++) {
+ if (!isspace(buf[i]) && !isdigit(buf[i])) {
+ ls->decpoint = buf[i];
+ break;
+ }
+ }
buffreplace(ls, old, ls->decpoint); /* try updated decimal separator */
if (!luaO_str2d(luaZ_buffer(ls->buff), &seminfo->r)) {
/* format error with correct decimal point: no more options */
diff --git a/engines/sword25/util/lua/lmathlib.cpp b/engines/sword25/util/lua/lmathlib.cpp
index 7e64d75789..6c36bbcf4e 100644
--- a/engines/sword25/util/lua/lmathlib.cpp
+++ b/engines/sword25/util/lua/lmathlib.cpp
@@ -5,6 +5,10 @@
*/
+// FIXME: rand and srand should be replaced by a RandomSource
+#define FORBIDDEN_SYMBOL_EXCEPTION_rand
+#define FORBIDDEN_SYMBOL_EXCEPTION_srand
+
#include <stdlib.h>
// MSVC does not define M_PI, M_SQRT2 and other math defines by default.
// _USE_MATH_DEFINES must be defined in order to have these defined, thus
diff --git a/engines/sword25/util/lua/loadlib.cpp b/engines/sword25/util/lua/loadlib.cpp
index 2549e2bdb1..9795a575f5 100644
--- a/engines/sword25/util/lua/loadlib.cpp
+++ b/engines/sword25/util/lua/loadlib.cpp
@@ -9,10 +9,6 @@
*/
-#include <stdlib.h>
-#include <string.h>
-
-
#define loadlib_c
#define LUA_LIB
@@ -35,18 +31,6 @@
#define LIB_FAIL "open"
-/* error codes for ll_loadfunc */
-#define ERRLIB 1
-#define ERRFUNC 2
-
-#define setprogdir(L) ((void)0)
-
-
-static void ll_unloadlib (void *lib);
-static void *ll_load (lua_State *L, const char *path);
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
-
-
/*
** {======================================================
** Fallback for other systems
@@ -60,24 +44,6 @@ static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym);
#define DLMSG "dynamic libraries not enabled; check your Lua installation"
-static void ll_unloadlib (void *lib) {
- (void)lib; /* to avoid warnings */
-}
-
-
-static void *ll_load (lua_State *L, const char *path) {
- (void)path; /* to avoid warnings */
- lua_pushliteral(L, DLMSG);
- return NULL;
-}
-
-
-static lua_CFunction ll_sym (lua_State *L, void *lib, const char *sym) {
- (void)lib; (void)sym; /* to avoid warnings */
- lua_pushliteral(L, DLMSG);
- return NULL;
-}
-
/* }====================================================== */
@@ -108,39 +74,33 @@ static void **ll_register (lua_State *L, const char *path) {
*/
static int gctm (lua_State *L) {
void **lib = (void **)luaL_checkudata(L, 1, "_LOADLIB");
- if (*lib) ll_unloadlib(*lib);
*lib = NULL; /* mark library as closed */
return 0;
}
-static int ll_loadfunc (lua_State *L, const char *path, const char *sym) {
- void **reg = ll_register(L, path);
- if (*reg == NULL) *reg = ll_load(L, path);
- if (*reg == NULL)
- return ERRLIB; /* unable to load library */
- else {
- lua_CFunction f = ll_sym(L, *reg, sym);
- if (f == NULL)
- return ERRFUNC; /* unable to find function */
- lua_pushcfunction(L, f);
- return 0; /* return function */
- }
-}
+/* error codes for ll_loadfunc */
+#define ERRLIB 1
+#define ERRFUNC 2
static int ll_loadlib (lua_State *L) {
const char *path = luaL_checkstring(L, 1);
- const char *init = luaL_checkstring(L, 2);
- int stat = ll_loadfunc(L, path, init);
- if (stat == 0) /* no errors? */
- return 1; /* return the loaded function */
- else { /* error; error message is on stack top */
- lua_pushnil(L);
- lua_insert(L, -2);
- lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
- return 3; /* return nil, error message, and where */
+// const char *init = luaL_checkstring(L, 2);
+ int stat;
+ void **reg = ll_register(L, path);
+ if (*reg == NULL) {
+ stat = ERRLIB; /* unable to load library */
+ } else {
+ stat = ERRFUNC; /* unable to find function */
}
+ lua_pushliteral(L, DLMSG);
+
+ /* error; error message is on stack top */
+ lua_pushnil(L);
+ lua_insert(L, -2);
+ lua_pushstring(L, (stat == ERRLIB) ? LIB_FAIL : "init");
+ return 3; /* return nil, error message, and where */
}
@@ -152,109 +112,6 @@ static int ll_loadlib (lua_State *L) {
*/
-static int readable (const char *filename) {
- FILE *f = fopen(filename, "r"); /* try to open file */
- if (f == NULL) return 0; /* open failed */
- fclose(f);
- return 1;
-}
-
-
-static const char *pushnexttemplate (lua_State *L, const char *path) {
- const char *l;
- while (*path == *LUA_PATHSEP) path++; /* skip separators */
- if (*path == '\0') return NULL; /* no more templates */
- l = strchr(path, *LUA_PATHSEP); /* find next separator */
- if (l == NULL) l = path + strlen(path);
- lua_pushlstring(L, path, l - path); /* template */
- return l;
-}
-
-
-static const char *findfile (lua_State *L, const char *name,
- const char *pname) {
- const char *path;
- name = luaL_gsub(L, name, ".", LUA_DIRSEP);
- lua_getfield(L, LUA_ENVIRONINDEX, pname);
- path = lua_tostring(L, -1);
- if (path == NULL)
- luaL_error(L, LUA_QL("package.%s") " must be a string", pname);
- lua_pushliteral(L, ""); /* error accumulator */
- while ((path = pushnexttemplate(L, path)) != NULL) {
- const char *filename;
- filename = luaL_gsub(L, lua_tostring(L, -1), LUA_PATH_MARK, name);
- lua_remove(L, -2); /* remove path template */
- if (readable(filename)) /* does file exist and is readable? */
- return filename; /* return that file name */
- lua_pushfstring(L, "\n\tno file " LUA_QS, filename);
- lua_remove(L, -2); /* remove file name */
- lua_concat(L, 2); /* add entry to possible error message */
- }
- return NULL; /* not found */
-}
-
-
-static void loaderror (lua_State *L, const char *filename) {
- luaL_error(L, "error loading module " LUA_QS " from file " LUA_QS ":\n\t%s",
- lua_tostring(L, 1), filename, lua_tostring(L, -1));
-}
-
-
-static int loader_Lua (lua_State *L) {
- const char *filename;
- const char *name = luaL_checkstring(L, 1);
- filename = findfile(L, name, "path");
- if (filename == NULL) return 1; /* library not found in this path */
- if (luaL_loadfile(L, filename) != 0)
- loaderror(L, filename);
- return 1; /* library loaded successfully */
-}
-
-
-static const char *mkfuncname (lua_State *L, const char *modname) {
- const char *funcname;
- const char *mark = strchr(modname, *LUA_IGMARK);
- if (mark) modname = mark + 1;
- funcname = luaL_gsub(L, modname, ".", LUA_OFSEP);
- funcname = lua_pushfstring(L, POF"%s", funcname);
- lua_remove(L, -2); /* remove 'gsub' result */
- return funcname;
-}
-
-
-static int loader_C (lua_State *L) {
- const char *funcname;
- const char *name = luaL_checkstring(L, 1);
- const char *filename = findfile(L, name, "cpath");
- if (filename == NULL) return 1; /* library not found in this path */
- funcname = mkfuncname(L, name);
- if (ll_loadfunc(L, filename, funcname) != 0)
- loaderror(L, filename);
- return 1; /* library loaded successfully */
-}
-
-
-static int loader_Croot (lua_State *L) {
- const char *funcname;
- const char *filename;
- const char *name = luaL_checkstring(L, 1);
- const char *p = strchr(name, '.');
- int stat;
- if (p == NULL) return 0; /* is root */
- lua_pushlstring(L, name, p - name);
- filename = findfile(L, lua_tostring(L, -1), "cpath");
- if (filename == NULL) return 1; /* root not found */
- funcname = mkfuncname(L, name);
- if ((stat = ll_loadfunc(L, filename, funcname)) != 0) {
- if (stat != ERRFUNC) loaderror(L, filename); /* real error */
- lua_pushfstring(L, "\n\tno module " LUA_QS " in file " LUA_QS,
- name, filename);
- return 1; /* function not found */
- }
- return 1;
-}
-
-
static int loader_preload (lua_State *L) {
const char *name = luaL_checkstring(L, 1);
lua_getfield(L, LUA_ENVIRONINDEX, "preload");
@@ -407,23 +264,11 @@ static int ll_seeall (lua_State *L) {
-/* auxiliary mark (for internal use) */
-#define AUXMARK "\1"
-
static void setpath (lua_State *L, const char *fieldname, const char *envname,
const char *def) {
- const char *path = getenv(envname);
- if (path == NULL) /* no environment variable? */
- lua_pushstring(L, def); /* use default */
- else {
- /* replace ";;" by ";AUXMARK;" and then AUXMARK by default path */
- path = luaL_gsub(L, path, LUA_PATHSEP LUA_PATHSEP,
- LUA_PATHSEP AUXMARK LUA_PATHSEP);
- luaL_gsub(L, path, AUXMARK, def);
- lua_remove(L, -2);
- }
- setprogdir(L);
- lua_setfield(L, -2, fieldname);
+ // no environment variable -> use default
+ lua_pushstring(L, def);
+ lua_setfield(L, -2, fieldname);
}
@@ -442,7 +287,7 @@ static const luaL_Reg ll_funcs[] = {
static const lua_CFunction loaders[] =
- {loader_preload, loader_Lua, loader_C, loader_Croot, NULL};
+ {loader_preload, NULL};
LUALIB_API int luaopen_package (lua_State *L) {
diff --git a/engines/sword25/util/lua/loslib.cpp b/engines/sword25/util/lua/loslib.cpp
index 578a7cb09a..b61f8c65e1 100644
--- a/engines/sword25/util/lua/loslib.cpp
+++ b/engines/sword25/util/lua/loslib.cpp
@@ -4,9 +4,9 @@
** See Copyright Notice in lua.h
*/
+// FIXME: Get rid of all time.h stuff
+#define FORBIDDEN_SYMBOL_EXCEPTION_time_h
-#include <stdlib.h>
-#include <string.h>
#include <time.h>
#define loslib_c
@@ -17,9 +17,14 @@
#include "lauxlib.h"
#include "lualib.h"
+#include "common/system.h"
+#include "common/textconsole.h"
+
static int os_execute (lua_State *L) {
- lua_pushinteger(L, system(luaL_optstring(L, 1, NULL)));
+ // Non-portable call, removed in ScummVM.
+ // FIXME: Is this ever invoked? If so, investigate that code further.
+ lua_pushinteger(L, -1); // signal that an error occurred
return 1;
}
@@ -35,24 +40,30 @@ static int os_remove (lua_State *L) {
static int os_rename (lua_State *L) {
- // Removed in ScummVM, does nothing.
+ // Non-portable call, removed in ScummVM.
return 1;
}
static int os_tmpname (lua_State *L) {
+ // Non-portable call, removed in ScummVM.
+ // FIXME: Why do we return an error in tmpname, but for other
+ // removed methods we just do nothing?
return luaL_error(L, "unable to generate a unique filename");
}
static int os_getenv (lua_State *L) {
- lua_pushstring(L, getenv(luaL_checkstring(L, 1))); /* if NULL push nil */
+ // Non-portable call, removed in ScummVM.
+ // FIXME: Is this ever invoked? If so, investigate that code further.
+ lua_pushstring(L, NULL);
return 1;
}
static int os_clock (lua_State *L) {
- lua_pushnumber(L, ((lua_Number)clock())/(lua_Number)CLOCKS_PER_SEC);
+ // Non-portable call to clock() replaced by invocation of OSystem::getMillis.
+ lua_pushnumber(L, ((lua_Number)g_system->getMillis())/(lua_Number)1000);
return 1;
}
@@ -103,6 +114,12 @@ static int getfield (lua_State *L, const char *key, int d) {
static int os_date (lua_State *L) {
const char *s = luaL_optstring(L, 1, "%c");
+ // FIXME: Rewrite the code below to use OSystem::getTimeAndDate
+ // Alternatively, remove it, if sword25 does not use it.
+ //
+ // The former would mean sacrificing the ability to choose the timezone, *or*
+ // we would have to drive an effort to add time zone support to OSystem (is it
+ // worth that, though???)
time_t t = luaL_opt(L, (time_t)luaL_checknumber, 2, time(NULL));
struct tm *stm;
if (*s == '!') { /* UTC? */
@@ -148,6 +165,8 @@ static int os_date (lua_State *L) {
static int os_time (lua_State *L) {
+ // FIXME: Rewrite the code below to use OSystem::getTimeAndDate.
+ // Alternatively, remove it, if sword25 does not use it.
time_t t;
if (lua_isnoneornil(L, 1)) /* called without args? */
t = time(NULL); /* get current time */
@@ -173,6 +192,9 @@ static int os_time (lua_State *L) {
static int os_difftime (lua_State *L) {
+ // FIXME: difftime is not portable, unfortunately.
+ // So we either have to replace this code, or just remove it,
+ // depending on whether sword25 actually uses it.
lua_pushnumber(L, difftime((time_t)(luaL_checknumber(L, 1)),
(time_t)(luaL_optnumber(L, 2, 0))));
return 1;
@@ -189,7 +211,13 @@ static int os_setlocale (lua_State *L) {
static int os_exit (lua_State *L) {
- exit(luaL_optint(L, 1, EXIT_SUCCESS));
+ // FIXME: Using exit is not portable!
+ // Using OSystem::quit() isn't really a great idea, either.
+ // We really would prefer to let the main run loop exit, so that
+ // our main() can perform cleanup.
+ if (0 == luaL_optint(L, 1, EXIT_SUCCESS))
+ g_system->quit();
+ error("LUA os_exit invokes with non-zero exit value");
}
static const luaL_Reg syslib[] = {
diff --git a/engines/sword25/util/lua/lua.h b/engines/sword25/util/lua/lua.h
index 088a511cf9..417cdadf8b 100644
--- a/engines/sword25/util/lua/lua.h
+++ b/engines/sword25/util/lua/lua.h
@@ -9,6 +9,8 @@
#ifndef lua_h
#define lua_h
+#include "common/scummsys.h"
+
#include <stdarg.h>
#include <stddef.h>
diff --git a/engines/sword25/util/lua/luaconf.h b/engines/sword25/util/lua/luaconf.h
index 29411d5af1..f3509e969b 100644
--- a/engines/sword25/util/lua/luaconf.h
+++ b/engines/sword25/util/lua/luaconf.h
@@ -18,14 +18,6 @@
** ===================================================================
*/
-#if defined(__ANDROID__)
-/* Android is missing strcoll().
-** For more information, refer to:
-** http://www.damonkohler.com/2008/12/lua-on-android.html
-*/
-#define strcoll strcmp
-#endif
-
/*
@@ LUA_ANSI controls the use of non-ansi features.
@@ -357,7 +349,7 @@
/*
@@ LUA_COMPAT_LSTR controls compatibility with old long string nesting
@* facility.
-** CHANGE it to 2 if you want the old behaviour, or undefine it to turn
+** CHANGE it to 2 if you want the old behavior, or undefine it to turn
** off the advisory error when nesting [[...]].
*/
#define LUA_COMPAT_LSTR 1
diff --git a/engines/sword25/util/lua/lundump.cpp b/engines/sword25/util/lua/lundump.cpp
deleted file mode 100644
index 4ffc623575..0000000000
--- a/engines/sword25/util/lua/lundump.cpp
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
-** $Id$
-** load precompiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#include <string.h>
-
-#define lundump_c
-#define LUA_CORE
-
-#include "lua.h"
-
-#include "ldebug.h"
-#include "ldo.h"
-#include "lfunc.h"
-#include "lmem.h"
-#include "lobject.h"
-#include "lstring.h"
-#include "lundump.h"
-#include "lzio.h"
-
-typedef struct {
- lua_State* L;
- ZIO* Z;
- Mbuffer* b;
- const char* name;
-} LoadState;
-
-#ifdef LUAC_TRUST_BINARIES
-#define IF(c,s)
-#define error(S,s)
-#else
-#define IF(c,s) if (c) error(S,s)
-
-static void error(LoadState* S, const char* why)
-{
- luaO_pushfstring(S->L,"%s: %s in precompiled chunk",S->name,why);
- luaD_throw(S->L,LUA_ERRSYNTAX);
-}
-#endif
-
-#define LoadMem(S,b,n,size) LoadBlock(S,b,(n)*(size))
-#define LoadByte(S) (lu_byte)LoadChar(S)
-#define LoadVar(S,x) LoadMem(S,&x,1,sizeof(x))
-#define LoadVector(S,b,n,size) LoadMem(S,b,n,size)
-
-static void LoadBlock(LoadState* S, void* b, size_t size)
-{
- size_t r=luaZ_read(S->Z,b,size);
- UNUSED(r);
- IF (r!=0, "unexpected end");
-}
-
-static int LoadChar(LoadState* S)
-{
- char x;
- LoadVar(S,x);
- return x;
-}
-
-static int LoadInt(LoadState* S)
-{
- int x;
- LoadVar(S,x);
- IF (x<0, "bad integer");
- return x;
-}
-
-static lua_Number LoadNumber(LoadState* S)
-{
- lua_Number x;
- LoadVar(S,x);
- return x;
-}
-
-static TString* LoadString(LoadState* S)
-{
- size_t size;
- LoadVar(S,size);
- if (size==0)
- return NULL;
- else
- {
- char* s=luaZ_openspace(S->L,S->b,size);
- LoadBlock(S,s,size);
- return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
- }
-}
-
-static void LoadCode(LoadState* S, Proto* f)
-{
- int n=LoadInt(S);
- f->code=luaM_newvector(S->L,n,Instruction);
- f->sizecode=n;
- LoadVector(S,f->code,n,sizeof(Instruction));
-}
-
-static Proto* LoadFunction(LoadState* S, TString* p);
-
-static void LoadConstants(LoadState* S, Proto* f)
-{
- int i,n;
- n=LoadInt(S);
- f->k=luaM_newvector(S->L,n,TValue);
- f->sizek=n;
- for (i=0; i<n; i++) setnilvalue(&f->k[i]);
- for (i=0; i<n; i++)
- {
- TValue* o=&f->k[i];
- int t=LoadChar(S);
- switch (t)
- {
- case LUA_TNIL:
- setnilvalue(o);
- break;
- case LUA_TBOOLEAN:
- setbvalue(o,LoadChar(S));
- break;
- case LUA_TNUMBER:
- setnvalue(o,LoadNumber(S));
- break;
- case LUA_TSTRING:
- setsvalue2n(S->L,o,LoadString(S));
- break;
- default:
- error(S,"bad constant");
- break;
- }
- }
- n=LoadInt(S);
- f->p=luaM_newvector(S->L,n,Proto*);
- f->sizep=n;
- for (i=0; i<n; i++) f->p[i]=NULL;
- for (i=0; i<n; i++) f->p[i]=LoadFunction(S,f->source);
-}
-
-static void LoadDebug(LoadState* S, Proto* f)
-{
- int i,n;
- n=LoadInt(S);
- f->lineinfo=luaM_newvector(S->L,n,int);
- f->sizelineinfo=n;
- LoadVector(S,f->lineinfo,n,sizeof(int));
- n=LoadInt(S);
- f->locvars=luaM_newvector(S->L,n,LocVar);
- f->sizelocvars=n;
- for (i=0; i<n; i++) f->locvars[i].varname=NULL;
- for (i=0; i<n; i++)
- {
- f->locvars[i].varname=LoadString(S);
- f->locvars[i].startpc=LoadInt(S);
- f->locvars[i].endpc=LoadInt(S);
- }
- n=LoadInt(S);
- f->upvalues=luaM_newvector(S->L,n,TString*);
- f->sizeupvalues=n;
- for (i=0; i<n; i++) f->upvalues[i]=NULL;
- for (i=0; i<n; i++) f->upvalues[i]=LoadString(S);
-}
-
-static Proto* LoadFunction(LoadState* S, TString* p)
-{
- Proto* f=luaF_newproto(S->L);
- setptvalue2s(S->L,S->L->top,f); incr_top(S->L);
- f->source=LoadString(S); if (f->source==NULL) f->source=p;
- f->linedefined=LoadInt(S);
- f->lastlinedefined=LoadInt(S);
- f->nups=LoadByte(S);
- f->numparams=LoadByte(S);
- f->is_vararg=LoadByte(S);
- f->maxstacksize=LoadByte(S);
- LoadCode(S,f);
- LoadConstants(S,f);
- LoadDebug(S,f);
- IF (!luaG_checkcode(f), "bad code");
- S->L->top--;
- return f;
-}
-
-static void LoadHeader(LoadState* S)
-{
- char h[LUAC_HEADERSIZE];
- char s[LUAC_HEADERSIZE];
- luaU_header(h);
- LoadBlock(S,s,LUAC_HEADERSIZE);
- IF (memcmp(h,s,LUAC_HEADERSIZE)!=0, "bad header");
-}
-
-/*
-** load precompiled chunk
-*/
-Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name)
-{
- LoadState S;
- if (*name=='@' || *name=='=')
- S.name=name+1;
- else if (*name==LUA_SIGNATURE[0])
- S.name="binary string";
- else
- S.name=name;
- S.L=L;
- S.Z=Z;
- S.b=buff;
- LoadHeader(&S);
- return LoadFunction(&S,luaS_newliteral(L,"=?"));
-}
-
-/*
-* make header
-*/
-void luaU_header (char* h)
-{
- int x=1;
- memcpy(h,LUA_SIGNATURE,sizeof(LUA_SIGNATURE)-1);
- h+=sizeof(LUA_SIGNATURE)-1;
- *h++=(char)LUAC_VERSION;
- *h++=(char)LUAC_FORMAT;
- *h++=(char)*(char*)&x; /* endianness */
- *h++=(char)sizeof(int);
- *h++=(char)sizeof(size_t);
- *h++=(char)sizeof(Instruction);
- *h++=(char)sizeof(lua_Number);
- *h++=(char)(((lua_Number)0.5)==0); /* is lua_Number integral? */
-}
diff --git a/engines/sword25/util/lua/lundump.h b/engines/sword25/util/lua/lundump.h
deleted file mode 100644
index f791a4f173..0000000000
--- a/engines/sword25/util/lua/lundump.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
-** $Id$
-** load precompiled Lua chunks
-** See Copyright Notice in lua.h
-*/
-
-#ifndef lundump_h
-#define lundump_h
-
-#include "lobject.h"
-#include "lzio.h"
-
-/* load one chunk; from lundump.c */
-LUAI_FUNC Proto* luaU_undump (lua_State* L, ZIO* Z, Mbuffer* buff, const char* name);
-
-/* make header; from lundump.c */
-LUAI_FUNC void luaU_header (char* h);
-
-/* dump one chunk; from ldump.c */
-LUAI_FUNC int luaU_dump (lua_State* L, const Proto* f, lua_Writer w, void* data, int strip);
-
-#ifdef luac_c
-/* print one chunk; from print.c */
-LUAI_FUNC void luaU_print (const Proto* f, int full);
-#endif
-
-/* for header of binary files -- this is Lua 5.1 */
-#define LUAC_VERSION 0x51
-
-/* for header of binary files -- this is the official format */
-#define LUAC_FORMAT 0
-
-/* size of header of binary files */
-#define LUAC_HEADERSIZE 12
-
-#endif
diff --git a/engines/sword25/util/lua/lvm.cpp b/engines/sword25/util/lua/lvm.cpp
index ae70fe2645..fb700c20a2 100644
--- a/engines/sword25/util/lua/lvm.cpp
+++ b/engines/sword25/util/lua/lvm.cpp
@@ -202,7 +202,7 @@ static int l_strcmp (const TString *ls, const TString *rs) {
const char *r = getstr(rs);
size_t lr = rs->tsv.len;
for (;;) {
- int temp = strcoll(l, r);
+ int temp = strcmp(l, r);
if (temp != 0) return temp;
else { /* strings are equal up to a `\0' */
size_t len = strlen(l); /* index of first `\0' in both strings */
diff --git a/engines/sword25/util/lua/print.cpp b/engines/sword25/util/lua/print.cpp
deleted file mode 100644
index 22039c9861..0000000000
--- a/engines/sword25/util/lua/print.cpp
+++ /dev/null
@@ -1,227 +0,0 @@
-/*
-** $Id$
-** print bytecodes
-** See Copyright Notice in lua.h
-*/
-
-#include <ctype.h>
-#include <stdio.h>
-
-#define luac_c
-#define LUA_CORE
-
-#include "ldebug.h"
-#include "lobject.h"
-#include "lopcodes.h"
-#include "lundump.h"
-
-#define PrintFunction luaU_print
-
-#define Sizeof(x) ((int)sizeof(x))
-#define VOID(p) ((const void*)(p))
-
-static void PrintString(const TString* ts)
-{
- const char* s=getstr(ts);
- size_t i,n=ts->tsv.len;
- putchar('"');
- for (i=0; i<n; i++)
- {
- int c=s[i];
- switch (c)
- {
- case '"': printf("\\\""); break;
- case '\\': printf("\\\\"); break;
- case '\a': printf("\\a"); break;
- case '\b': printf("\\b"); break;
- case '\f': printf("\\f"); break;
- case '\n': printf("\\n"); break;
- case '\r': printf("\\r"); break;
- case '\t': printf("\\t"); break;
- case '\v': printf("\\v"); break;
- default: if (isprint((unsigned char)c))
- putchar(c);
- else
- printf("\\%03u",(unsigned char)c);
- }
- }
- putchar('"');
-}
-
-static void PrintConstant(const Proto* f, int i)
-{
- const TValue* o=&f->k[i];
- switch (ttype(o))
- {
- case LUA_TNIL:
- printf("nil");
- break;
- case LUA_TBOOLEAN:
- printf(bvalue(o) ? "true" : "false");
- break;
- case LUA_TNUMBER:
- printf(LUA_NUMBER_FMT,nvalue(o));
- break;
- case LUA_TSTRING:
- PrintString(rawtsvalue(o));
- break;
- default: /* cannot happen */
- printf("? type=%d",ttype(o));
- break;
- }
-}
-
-static void PrintCode(const Proto* f)
-{
- const Instruction* code=f->code;
- int pc,n=f->sizecode;
- for (pc=0; pc<n; pc++)
- {
- Instruction i=code[pc];
- OpCode o=GET_OPCODE(i);
- int a=GETARG_A(i);
- int b=GETARG_B(i);
- int c=GETARG_C(i);
- int bx=GETARG_Bx(i);
- int sbx=GETARG_sBx(i);
- int line=getline(f,pc);
- printf("\t%d\t",pc+1);
- if (line>0) printf("[%d]\t",line); else printf("[-]\t");
- printf("%-9s\t",luaP_opnames[o]);
- switch (getOpMode(o))
- {
- case iABC:
- printf("%d",a);
- if (getBMode(o)!=OpArgN) printf(" %d",ISK(b) ? (-1-INDEXK(b)) : b);
- if (getCMode(o)!=OpArgN) printf(" %d",ISK(c) ? (-1-INDEXK(c)) : c);
- break;
- case iABx:
- if (getBMode(o)==OpArgK) printf("%d %d",a,-1-bx); else printf("%d %d",a,bx);
- break;
- case iAsBx:
- if (o==OP_JMP) printf("%d",sbx); else printf("%d %d",a,sbx);
- break;
- }
- switch (o)
- {
- case OP_LOADK:
- printf("\t; "); PrintConstant(f,bx);
- break;
- case OP_GETUPVAL:
- case OP_SETUPVAL:
- printf("\t; %s", (f->sizeupvalues>0) ? getstr(f->upvalues[b]) : "-");
- break;
- case OP_GETGLOBAL:
- case OP_SETGLOBAL:
- printf("\t; %s",svalue(&f->k[bx]));
- break;
- case OP_GETTABLE:
- case OP_SELF:
- if (ISK(c)) { printf("\t; "); PrintConstant(f,INDEXK(c)); }
- break;
- case OP_SETTABLE:
- case OP_ADD:
- case OP_SUB:
- case OP_MUL:
- case OP_DIV:
- case OP_POW:
- case OP_EQ:
- case OP_LT:
- case OP_LE:
- if (ISK(b) || ISK(c))
- {
- printf("\t; ");
- if (ISK(b)) PrintConstant(f,INDEXK(b)); else printf("-");
- printf(" ");
- if (ISK(c)) PrintConstant(f,INDEXK(c)); else printf("-");
- }
- break;
- case OP_JMP:
- case OP_FORLOOP:
- case OP_FORPREP:
- printf("\t; to %d",sbx+pc+2);
- break;
- case OP_CLOSURE:
- printf("\t; %p",VOID(f->p[bx]));
- break;
- case OP_SETLIST:
- if (c==0) printf("\t; %d",(int)code[++pc]);
- else printf("\t; %d",c);
- break;
- default:
- break;
- }
- printf("\n");
- }
-}
-
-#define SS(x) (x==1)?"":"s"
-#define S(x) x,SS(x)
-
-static void PrintHeader(const Proto* f)
-{
- const char* s=getstr(f->source);
- if (*s=='@' || *s=='=')
- s++;
- else if (*s==LUA_SIGNATURE[0])
- s="(bstring)";
- else
- s="(string)";
- printf("\n%s <%s:%d,%d> (%d instruction%s, %d bytes at %p)\n",
- (f->linedefined==0)?"main":"function",s,
- f->linedefined,f->lastlinedefined,
- S(f->sizecode),f->sizecode*Sizeof(Instruction),VOID(f));
- printf("%d%s param%s, %d slot%s, %d upvalue%s, ",
- f->numparams,f->is_vararg?"+":"",SS(f->numparams),
- S(f->maxstacksize),S(f->nups));
- printf("%d local%s, %d constant%s, %d function%s\n",
- S(f->sizelocvars),S(f->sizek),S(f->sizep));
-}
-
-static void PrintConstants(const Proto* f)
-{
- int i,n=f->sizek;
- printf("constants (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t",i+1);
- PrintConstant(f,i);
- printf("\n");
- }
-}
-
-static void PrintLocals(const Proto* f)
-{
- int i,n=f->sizelocvars;
- printf("locals (%d) for %p:\n",n,VOID(f));
- for (i=0; i<n; i++)
- {
- printf("\t%d\t%s\t%d\t%d\n",
- i,getstr(f->locvars[i].varname),f->locvars[i].startpc+1,f->locvars[i].endpc+1);
- }
-}
-
-static void PrintUpvalues(const Proto* f)
-{
- int i,n=f->sizeupvalues;
- printf("upvalues (%d) for %p:\n",n,VOID(f));
- if (f->upvalues==NULL) return;
- for (i=0; i<n; i++)
- {
- printf("\t%d\t%s\n",i,getstr(f->upvalues[i]));
- }
-}
-
-void PrintFunction(const Proto* f, int full)
-{
- int i,n=f->sizep;
- PrintHeader(f);
- PrintCode(f);
- if (full)
- {
- PrintConstants(f);
- PrintLocals(f);
- PrintUpvalues(f);
- }
- for (i=0; i<n; i++) PrintFunction(f->p[i],full);
-}
diff --git a/engines/sword25/util/lua/scummvm_file.cpp b/engines/sword25/util/lua/scummvm_file.cpp
new file mode 100644
index 0000000000..3c0377d0ee
--- /dev/null
+++ b/engines/sword25/util/lua/scummvm_file.cpp
@@ -0,0 +1,205 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include "sword25/util/lua/scummvm_file.h"
+#include "common/config-manager.h"
+#include "common/util.h"
+
+namespace Sword25 {
+
+Sword25FileProxy::Sword25FileProxy(const Common::String &filename, const Common::String &mode) {
+ assert(filename.contains("config.lua"));
+ if (mode == "r")
+ setupConfigFile();
+}
+
+void Sword25FileProxy::setupConfigFile() {
+ double sfxVolume = ConfMan.hasKey("sfx_volume") ? 1.0 : 1.0 * ConfMan.getInt("sfx_volume") / 255.0;
+ double musicVolume = ConfMan.hasKey("music_volume") ? 0.5 : 1.0 * ConfMan.getInt("music_volume") / 255.0;
+ double speechVolume = ConfMan.hasKey("speech_volume") ? 1.0 : 1.0 * ConfMan.getInt("speech_volume") / 255.0;
+ bool subtitles = ConfMan.hasKey("subtitles") ? true : ConfMan.getBool("subtitles");
+
+ _readData = Common::String::format(
+"GAME_LANGUAGE = \"%s\"\r\n\
+GAME_SUBTITLES = %s\r\n\
+MAX_MEMORY_USAGE = 256000000\r\n\
+GFX_VSYNC_ACTIVE = true\r\n\
+SFX_SAMPLING_RATE = 44100\r\n\
+SFX_CHANNEL_COUNT = 32\r\n\
+SFX_SOUND_VOLUME = %f\r\n\
+SFX_MUSIC_VOLUME = %f\r\n\
+SFX_SPEECH_VOLUME = %f\r\n",
+ getLanguage().c_str(), subtitles ? "true" : "false", sfxVolume, musicVolume, speechVolume);
+
+ _readPos = 0;
+}
+
+Sword25FileProxy::~Sword25FileProxy() {
+ if (!_settings.empty())
+ writeSettings();
+}
+
+size_t Sword25FileProxy::read(void *ptr, size_t size, size_t count) {
+ size_t bytesRead = MIN<size_t>(_readData.size() - _readPos, size * count);
+ memmove(ptr, &_readData.c_str()[_readPos], bytesRead);
+ _readPos += bytesRead;
+ return bytesRead / size;
+}
+
+size_t Sword25FileProxy::write(const char *ptr, size_t count) {
+ // Loop through the provided line(s)
+ while (*ptr) {
+ if ((*ptr == '-') && (*(ptr + 1) == '-')) {
+ // Comment line to skip over
+ while ((*ptr != '\r') && (*ptr != '\n'))
+ ++ptr;
+ } else {
+ // Legitimate data
+ const char *p = strchr(ptr, '\n');
+ if (!p) p = ptr + strlen(ptr);
+ while ((*p == '\r') || (*p == '\n'))
+ ++p;
+
+ _settings += Common::String(ptr, p - ptr);
+ ptr = p;
+ }
+
+ while ((*ptr == '\r') || (*ptr == '\n'))
+ ++ptr;
+ }
+
+ return count;
+}
+
+void Sword25FileProxy::writeSettings() {
+ // Loop through the setting lines
+ const char *pSrc = _settings.c_str();
+ while (*pSrc) {
+ if ((*pSrc != '\r') && (*pSrc != '\n')) {
+ const char *p = strchr(pSrc, '=');
+ assert(p);
+
+ // Get the setting name
+ const char *pEnd = p - 1;
+ while (*pEnd == ' ')
+ --pEnd;
+ Common::String settingName(pSrc, pEnd - pSrc + 1);
+
+ // Get the setting value
+ const char *pStart = p + 1;
+ while (*pStart == ' ')
+ ++pStart;
+
+ pEnd = pStart + 1;
+ while ((*pEnd != '\r') && (*pEnd != '\n') && (*pEnd != '\0'))
+ ++pEnd;
+ Common::String value(pStart + (*pStart == '"' ? 1 : 0), pEnd - pStart - (*pStart == '"' ? 2 : 0));
+
+ // Update the setting
+ updateSetting(settingName, value);
+ pSrc = pEnd;
+ }
+
+ // Move to next line
+ while ((*pSrc == '\r') || (*pSrc == '\n'))
+ ++pSrc;
+ }
+
+ ConfMan.flushToDisk();
+}
+
+void Sword25FileProxy::updateSetting(const Common::String &setting, const Common::String &value) {
+ if (setting == "GAME_LANGUAGE")
+ setLanguage(value);
+ else if (setting == "GAME_SUBTITLES")
+ ConfMan.setBool("subtitles", value == "true");
+ else if (setting == "SFX_SOUND_VOLUME") {
+ double v = strtod(value.c_str(), NULL);
+ ConfMan.setInt("sfx_volume", (int)(v * 255));
+ } else if (setting == "SFX_MUSIC_VOLUME") {
+ double v = strtod(value.c_str(), NULL);
+ ConfMan.setInt("music_volume", (int)(v * 255));
+ } else if (setting == "SFX_SPEECH_VOLUME") {
+ double v = strtod(value.c_str(), NULL);
+ ConfMan.setInt("speech_volume", (int)(v * 255));
+ } else {
+ // All other settings are ignored
+ }
+}
+
+/**
+ * Get the language code used by the game for each language it supports
+ */
+Common::String Sword25FileProxy::getLanguage() {
+ Common::Language lang = Common::parseLanguage(ConfMan.get("language"));
+ switch (lang) {
+ case Common::EN_ANY:
+ return "en";
+ case Common::DE_DEU:
+ return "de";
+ case Common::ES_ESP:
+ return "es";
+ case Common::FR_FRA:
+ return "fr";
+ case Common::HU_HUN:
+ return "hr";
+ case Common::IT_ITA:
+ return "it";
+ case Common::PL_POL:
+ return "pl";
+ case Common::PT_BRA:
+ return "pt";
+ case Common::RU_RUS:
+ return "ru";
+ default:
+ error("Unknown language '%s' encountered", ConfMan.get("language").c_str());
+ break;
+ }
+}
+
+/**
+ * Set the language code fro the game
+ */
+void Sword25FileProxy::setLanguage(const Common::String &lang) {
+ if (lang == "en")
+ ConfMan.set("language", Common::getLanguageCode(Common::EN_ANY));
+ else if (lang == "de")
+ ConfMan.set("language", Common::getLanguageCode(Common::DE_DEU));
+ else if (lang == "es")
+ ConfMan.set("language", Common::getLanguageCode(Common::ES_ESP));
+ else if (lang == "fr")
+ ConfMan.set("language", Common::getLanguageCode(Common::FR_FRA));
+ else if (lang == "hr")
+ ConfMan.set("language", Common::getLanguageCode(Common::HU_HUN));
+ else if (lang == "it")
+ ConfMan.set("language", Common::getLanguageCode(Common::IT_ITA));
+ else if (lang == "pl")
+ ConfMan.set("language", Common::getLanguageCode(Common::PL_POL));
+ else if (lang == "pt")
+ ConfMan.set("language", Common::getLanguageCode(Common::PT_BRA));
+ else if (lang == "ru")
+ ConfMan.set("language", Common::getLanguageCode(Common::RU_RUS));
+ else
+ error("Unknown language encountered");
+}
+
+} // End of namespace Sword25
diff --git a/engines/sword25/util/lua/scummvm_file.h b/engines/sword25/util/lua/scummvm_file.h
new file mode 100644
index 0000000000..a4cbd2a6cf
--- /dev/null
+++ b/engines/sword25/util/lua/scummvm_file.h
@@ -0,0 +1,56 @@
+/* ScummVM - Graphic Adventure Engine
+ *
+ * ScummVM is the legal property of its developers, whose names
+ * are too numerous to list here. Please refer to the COPYRIGHT
+ * file distributed with this source distribution.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ */
+
+#ifndef SWORD25_SCUMMVM_FILE_H
+#define SWORD25_SCUMMVM_FILE_H
+
+#include "common/str.h"
+
+namespace Sword25 {
+
+/**
+ * The following class acts as a proxy interface to the I/O code, pretending that the ScummVM
+ * settings are a properly formatted 'config.lua' file
+ */
+class Sword25FileProxy {
+private:
+ Common::String _readData;
+ uint _readPos;
+ Common::String _settings;
+
+ void setupConfigFile();
+ Common::String getLanguage();
+ void setLanguage(const Common::String &lang);
+ void writeSettings();
+ void updateSetting(const Common::String &setting, const Common::String &value);
+public:
+ Sword25FileProxy(const Common::String &filename, const Common::String &mode);
+ ~Sword25FileProxy();
+
+ bool eof() const { return _readPos >= _readData.size(); }
+ size_t read(void *ptr, size_t size, size_t count);
+ size_t write(const char *ptr, size_t count);
+};
+
+} // End of namespace Sword25
+
+#endif