diff options
Diffstat (limited to 'engines/sword25')
47 files changed, 421 insertions, 224 deletions
diff --git a/engines/sword25/detection_tables.h b/engines/sword25/detection_tables.h index ca586b4f01..fe9e6e7934 100644 --- a/engines/sword25/detection_tables.h +++ b/engines/sword25/detection_tables.h @@ -34,7 +34,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("data.b25c", "f8b6e03ada2d2f6cf27fbc11ad1572e9", 654310588), Common::EN_ANY, Common::kPlatformUnknown, - ADGF_NO_FLAGS, + ADGF_UNSTABLE, Common::GUIO_NONE }, { @@ -43,7 +43,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_fr.b25c", "690caf157387e06d2c3d1ca53c43f428", 1006043), Common::FR_FRA, Common::kPlatformUnknown, - ADGF_NO_FLAGS, + ADGF_UNSTABLE, Common::GUIO_NONE }, { @@ -52,7 +52,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("data.b25c", "f8b6e03ada2d2f6cf27fbc11ad1572e9", 654310588), Common::DE_DEU, Common::kPlatformUnknown, - ADGF_NO_FLAGS, + ADGF_UNSTABLE, Common::GUIO_NONE }, { @@ -61,7 +61,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_hr.b25c", "e881054d1f8ec1e527422fc521c25405", 1273217), Common::HU_HUN, Common::kPlatformUnknown, - ADGF_NO_FLAGS, + ADGF_UNSTABLE, Common::GUIO_NONE }, { @@ -70,7 +70,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_it.b25c", "f3325666da0515cc2b42062e953c0889", 996197), Common::IT_ITA, Common::kPlatformUnknown, - ADGF_NO_FLAGS, + ADGF_UNSTABLE, Common::GUIO_NONE }, { @@ -79,7 +79,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_pl.b25c", "49dc1a20f95391a808e475c49be2bac0", 1281799), Common::PL_POL, Common::kPlatformUnknown, - ADGF_NO_FLAGS, + ADGF_UNSTABLE, Common::GUIO_NONE }, { @@ -88,7 +88,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_pt.b25c", "1df701432f9e13dcefe1adeb890b9c69", 993812), Common::PT_BRA, Common::kPlatformUnknown, - ADGF_NO_FLAGS, + ADGF_UNSTABLE, Common::GUIO_NONE }, { @@ -97,7 +97,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_ru.b25c", "deb33dd2f90a71ff60181918a8ce5063", 1235378), Common::RU_RUS, Common::kPlatformUnknown, - ADGF_NO_FLAGS, + ADGF_UNSTABLE, Common::GUIO_NONE }, { @@ -106,7 +106,7 @@ static const ADGameDescription gameDescriptions[] = { AD_ENTRY1s("lang_es.b25c", "384c19072d83725f351bb9ecb4d3f02b", 987965), Common::ES_ESP, Common::kPlatformUnknown, - ADGF_NO_FLAGS, + ADGF_UNSTABLE, Common::GUIO_NONE }, @@ -120,7 +120,7 @@ static const ADGameDescription gameDescriptions[] = { AD_LISTEND}, Common::EN_ANY, Common::kPlatformUnknown, - GF_EXTRACTED, + GF_EXTRACTED | ADGF_UNSTABLE, Common::GUIO_NONE }, AD_TABLE_END_MARKER diff --git a/engines/sword25/fmv/theora_decoder.cpp b/engines/sword25/fmv/theora_decoder.cpp index 098bd2c6b9..a7ebb5df8c 100644 --- a/engines/sword25/fmv/theora_decoder.cpp +++ b/engines/sword25/fmv/theora_decoder.cpp @@ -424,6 +424,12 @@ bool TheoraDecoder::queueAudio() { if (!_audStream) return false; + // An audio buffer should have been allocated (either in the constructor or after queuing the current buffer) + if (!_audiobuf) { + warning("[TheoraDecoder::queueAudio] Invalid audio buffer"); + return false; + } + bool queuedAudio = false; for (;;) { @@ -454,6 +460,11 @@ bool TheoraDecoder::queueAudio() { // The audio mixer is now responsible for the old audio buffer. // We need to create a new one. _audiobuf = (ogg_int16_t *)malloc(AUDIOFD_FRAGSIZE * sizeof(ogg_int16_t)); + if (!_audiobuf) { + warning("[TheoraDecoder::queueAudio] Cannot allocate memory for audio buffer"); + return false; + } + _audiobufFill = 0; queuedAudio = true; } diff --git a/engines/sword25/gfx/animation.h b/engines/sword25/gfx/animation.h index 55deacd333..60070be214 100644 --- a/engines/sword25/gfx/animation.h +++ b/engines/sword25/gfx/animation.h @@ -210,7 +210,7 @@ private: AnimationDescription *getAnimationDescription() const; /** - * Initializes a new animation resource from an XML file. + * Initializes a new animation resource from an XML file. */ void initializeAnimationResource(const Common::String &fileName); }; diff --git a/engines/sword25/gfx/animationresource.cpp b/engines/sword25/gfx/animationresource.cpp index b9d70cf87b..621e20ad8c 100644 --- a/engines/sword25/gfx/animationresource.cpp +++ b/engines/sword25/gfx/animationresource.cpp @@ -64,7 +64,7 @@ AnimationResource::AnimationResource(const Common::String &filename) : char *xmlData = _pPackage->getXmlFile(getFileName(), &fileSize); if (!xmlData) { error("Could not read \"%s\".", getFileName().c_str()); - return; + return; } // Parse the contents @@ -118,7 +118,7 @@ bool AnimationResource::parserCallback_animation(ParserNode *node) { // Loop type value const char *loopTypeString = node->values["type"].c_str(); - + if (strcmp(loopTypeString, "oneshot") == 0) { _animationType = Animation::AT_ONESHOT; } else if (strcmp(loopTypeString, "loop") == 0) { @@ -148,7 +148,7 @@ bool AnimationResource::parserCallback_frame(ParserNode *node) { } frame.fileName = _pPackage->getAbsolutePath(fileString); if (frame.fileName.empty()) { - error("Could not create absolute path for file specified in <frame> tag in \"%s\": \"%s\".", + error("Could not create absolute path for file specified in <frame> tag in \"%s\": \"%s\".", getFileName().c_str(), fileString); return false; } diff --git a/engines/sword25/gfx/animationtemplateregistry.cpp b/engines/sword25/gfx/animationtemplateregistry.cpp index 43c099c89d..8184b49eba 100644 --- a/engines/sword25/gfx/animationtemplateregistry.cpp +++ b/engines/sword25/gfx/animationtemplateregistry.cpp @@ -34,7 +34,9 @@ #include "sword25/gfx/animationtemplateregistry.h" #include "sword25/gfx/animationtemplate.h" +namespace Common { DECLARE_SINGLETON(Sword25::AnimationTemplateRegistry); +} namespace Sword25 { diff --git a/engines/sword25/gfx/fontresource.cpp b/engines/sword25/gfx/fontresource.cpp index 7657abb5f2..0aeca7c180 100644 --- a/engines/sword25/gfx/fontresource.cpp +++ b/engines/sword25/gfx/fontresource.cpp @@ -85,7 +85,7 @@ bool FontResource::parserCallback_font(ParserNode *node) { getFileName().c_str(), DEFAULT_GAPWIDTH); _gapWidth = DEFAULT_GAPWIDTH; } - + // Get a reference to the package manager assert(_pKernel); PackageManager *pPackage = _pKernel->getPackage(); diff --git a/engines/sword25/gfx/graphicengine.cpp b/engines/sword25/gfx/graphicengine.cpp index 6b1c2bc514..14ba032107 100644 --- a/engines/sword25/gfx/graphicengine.cpp +++ b/engines/sword25/gfx/graphicengine.cpp @@ -156,7 +156,7 @@ RenderObjectPtr<Panel> GraphicEngine::getMainPanel() { } void GraphicEngine::setVsync(bool vsync) { - warning("STUB: SetVsync(%d)", vsync); + // ScummVM has no concept of VSync } bool GraphicEngine::getVsync() const { @@ -365,7 +365,7 @@ void GraphicEngine::updateLastFrameDuration() { } bool GraphicEngine::saveThumbnailScreenshot(const Common::String &filename) { - // Note: In ScumMVM, rather than saivng the thumbnail to a file, we store it in memory + // Note: In ScumMVM, rather than saivng the thumbnail to a file, we store it in memory // until needed when creating savegame files delete _thumbnail; diff --git a/engines/sword25/gfx/image/art.cpp b/engines/sword25/gfx/image/art.cpp index cd7cfb6b69..2ba102e779 100644 --- a/engines/sword25/gfx/image/art.cpp +++ b/engines/sword25/gfx/image/art.cpp @@ -151,6 +151,8 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) { n_segs_max = 16; svp = (ArtSVP *)malloc(sizeof(ArtSVP) + (n_segs_max - 1) * sizeof(ArtSVPSeg)); + if (!svp) + error("[art_svp_from_vpath] Cannot allocate memory"); dir = 0; n_points = 0; @@ -167,9 +169,14 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) { if (points != NULL && n_points >= 2) { if (n_segs == n_segs_max) { n_segs_max <<= 1; - svp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) + - (n_segs_max - 1) * - sizeof(ArtSVPSeg)); + ArtSVP *tmp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) + + (n_segs_max - 1) * + sizeof(ArtSVPSeg)); + + if (!tmp) + error("Cannot reallocate memory in art_svp_from_vpath()"); + + svp = tmp; } svp->segs[n_segs].n_points = n_points; svp->segs[n_segs].dir = (dir > 0); @@ -204,9 +211,14 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) { y = points[n_points - 1].y; if (n_segs == n_segs_max) { n_segs_max <<= 1; - svp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) + - (n_segs_max - 1) * - sizeof(ArtSVPSeg)); + ArtSVP *tmp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) + + (n_segs_max - 1) * + sizeof(ArtSVPSeg)); + + if (!tmp) + error("Cannot reallocate memory in art_svp_from_vpath()"); + + svp = tmp; } svp->segs[n_segs].n_points = n_points; svp->segs[n_segs].dir = (dir > 0); @@ -246,9 +258,14 @@ ArtSVP *art_svp_from_vpath(ArtVpath *vpath) { if (n_points >= 2) { if (n_segs == n_segs_max) { n_segs_max <<= 1; - svp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) + - (n_segs_max - 1) * - sizeof(ArtSVPSeg)); + ArtSVP *tmp = (ArtSVP *)realloc(svp, sizeof(ArtSVP) + + (n_segs_max - 1) * + sizeof(ArtSVPSeg)); + + if (!tmp) + error("Cannot reallocate memory in art_svp_from_vpath()"); + + svp = tmp; } svp->segs[n_segs].n_points = n_points; svp->segs[n_segs].dir = (dir > 0); @@ -1026,6 +1043,8 @@ struct _ArtPriPoint { static ArtPriQ *art_pri_new(void) { ArtPriQ *result = art_new(ArtPriQ, 1); + if (!result) + error("[art_pri_new] Cannot allocate memory"); result->n_items = 0; result->n_items_max = 16; @@ -1157,8 +1176,13 @@ static int art_svp_writer_rewind_add_segment(ArtSvpWriter *self, int wind_left, (swr->n_segs_max - 1) * sizeof(ArtSVPSeg)); swr->svp = svp; - swr->n_points_max = art_renew(swr->n_points_max, int, - swr->n_segs_max); + int *tmp = art_renew(swr->n_points_max, int, + swr->n_segs_max); + + if (!tmp) + error("Cannot reallocate memory in art_svp_writer_rewind_add_segment()"); + + swr->n_points_max = tmp; } seg = &svp->segs[seg_num]; seg->n_points = 1; @@ -1169,6 +1193,9 @@ static int art_svp_writer_rewind_add_segment(ArtSvpWriter *self, int wind_left, seg->bbox.x1 = x; seg->bbox.y1 = y; seg->points = art_new(ArtPoint, init_n_points_max); + if (!seg->points) + error("[art_svp_writer_rewind_add_segment] Cannot allocate memory"); + seg->points[0].x = x; seg->points[0].y = y; return seg_num; @@ -1213,6 +1240,8 @@ ArtSVP *art_svp_writer_rewind_reap(ArtSvpWriter *self) { ArtSvpWriter *art_svp_writer_rewind_new(ArtWindRule rule) { ArtSvpWriterRewind *result = art_new(ArtSvpWriterRewind, 1); + if (!result) + error("[art_svp_writer_rewind_new] Cannot allocate memory"); result->super.add_segment = art_svp_writer_rewind_add_segment; result->super.add_point = art_svp_writer_rewind_add_point; @@ -1222,6 +1251,9 @@ ArtSvpWriter *art_svp_writer_rewind_new(ArtWindRule rule) { result->n_segs_max = 16; result->svp = (ArtSVP *)malloc(sizeof(ArtSVP) + (result->n_segs_max - 1) * sizeof(ArtSVPSeg)); + if (!result->svp) + error("[art_svp_writer_rewind_new] Cannot allocate memory"); + result->svp->n_segs = 0; result->n_points_max = art_new(int, result->n_segs_max); @@ -1392,6 +1424,9 @@ static void art_svp_intersect_push_pt(ArtIntersectCtx *ctx, ArtActiveSeg *seg, seg->y1 = y; pri_pt = art_new(ArtPriPoint, 1); + if (!pri_pt) + error("[art_svp_intersect_push_pt] Cannot allocate memory"); + pri_pt->x = x; pri_pt->y = y; pri_pt->user_data = seg; @@ -1855,6 +1890,8 @@ static void art_svp_intersect_horiz(ArtIntersectCtx *ctx, ArtActiveSeg *seg, return; hs = art_new(ArtActiveSeg, 1); + if (!hs) + error("[art_svp_intersect_horiz] Cannot allocate memory"); hs->flags = ART_ACTIVE_FLAGS_DEL | (seg->flags & ART_ACTIVE_FLAGS_OUT); if (seg->flags & ART_ACTIVE_FLAGS_OUT) { @@ -1993,10 +2030,11 @@ static void art_svp_intersect_add_seg(ArtIntersectCtx *ctx, const ArtSVPSeg *in_ ArtActiveSeg *seg = art_new(ArtActiveSeg, 1); ArtActiveSeg *test; double x0, y0; - ArtActiveSeg *beg_range; ArtActiveSeg *last = NULL; ArtActiveSeg *left, *right; ArtPriPoint *pri_pt = art_new(ArtPriPoint, 1); + if (!pri_pt) + error("[art_svp_intersect_add_seg] Cannot allocate memory"); seg->flags = 0; seg->in_seg = in_seg; @@ -2019,7 +2057,6 @@ static void art_svp_intersect_add_seg(ArtIntersectCtx *ctx, const ArtSVPSeg *in_ x0 = in_seg->points[0].x; y0 = in_seg->points[0].y; - beg_range = NULL; for (test = ctx->active_head; test != NULL; test = test->right) { double d; int test_bneg = test->flags & ART_ACTIVE_FLAGS_BNEG; @@ -2166,6 +2203,9 @@ void art_svp_intersector(const ArtSVP *in, ArtSvpWriter *out) { return; ctx = art_new(ArtIntersectCtx, 1); + if (!ctx) + error("[art_svp_intersector] Cannot allocate memory"); + ctx->in = in; ctx->out = out; pq = art_pri_new(); @@ -2178,6 +2218,9 @@ void art_svp_intersector(const ArtSVP *in, ArtSvpWriter *out) { ctx->in_curs = 0; first_point = art_new(ArtPriPoint, 1); + if (!first_point) + error("[art_svp_intersector] Cannot allocate memory"); + first_point->x = in->segs[0].points[0].x; first_point->y = in->segs[0].points[0].y; first_point->user_data = NULL; @@ -2319,6 +2362,8 @@ static void art_svp_render_delete_active(int *active_segs, int j, int n_active_s ArtSVPRenderAAIter *art_svp_render_aa_iter(const ArtSVP *svp, int x0, int y0, int x1, int y1) { ArtSVPRenderAAIter *iter = art_new(ArtSVPRenderAAIter, 1); + if (!iter) + error("[art_svp_render_aa_iter] Cannot allocate memory"); iter->svp = svp; iter->y = y0; @@ -2499,7 +2544,7 @@ void art_svp_render_aa_iter_step(ArtSVPRenderAAIter *iter, int *p_start, ADD_STEP(x, xdelta) } if (x < x1) { - this_ = + this_ = (int)(delta * (1 - 0.5 * (x_max - ix_max) * (x_max - ix_max) * rslope)); diff --git a/engines/sword25/gfx/image/art.h b/engines/sword25/gfx/image/art.h index bfeb31cc30..8c9c97bc57 100644 --- a/engines/sword25/gfx/image/art.h +++ b/engines/sword25/gfx/image/art.h @@ -51,10 +51,13 @@ namespace Sword25 { #define art_expand(p, type, max) \ do { \ if(max) {\ - p = art_renew(p, type, max <<= 1); \ + type *tmp = art_renew(p, type, max <<= 1); \ + if (!tmp) error("Cannot reallocate memory for art data"); \ + p = tmp; \ } else { \ max = 1; \ p = art_new(type, 1); \ + if (!p) error("Cannot allocate memory for art data"); \ } \ } while (0) diff --git a/engines/sword25/gfx/image/renderedimage.cpp b/engines/sword25/gfx/image/renderedimage.cpp index a9c9de4f0c..3b29b0333f 100644 --- a/engines/sword25/gfx/image/renderedimage.cpp +++ b/engines/sword25/gfx/image/renderedimage.cpp @@ -72,7 +72,10 @@ static byte *readSavegameThumbnail(const Common::String &filename, uint &fileSiz // Seek to the actual PNG image loadString(*file); // Marker (BS25SAVEGAME) - loadString(*file); // Version + Common::String storedVersionID = loadString(*file); // Version + if (storedVersionID != "SCUMMVM1") + loadString(*file); + loadString(*file); // Description uint32 compressedGamedataSize = atoi(loadString(*file).c_str()); loadString(*file); // Uncompressed game data size @@ -373,17 +376,23 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe default: // alpha blending #if defined(SCUMM_LITTLE_ENDIAN) - if (cb != 255) + if (cb == 0) + *out = 0; + else if (cb != 255) *out += ((b - *out) * a * cb) >> 16; else *out += ((b - *out) * a) >> 8; out++; - if (cg != 255) + if (cg == 0) + *out = 0; + else if (cg != 255) *out += ((g - *out) * a * cg) >> 16; else *out += ((g - *out) * a) >> 8; out++; - if (cr != 255) + if (cr == 0) + *out = 0; + else if (cr != 255) *out += ((r - *out) * a * cr) >> 16; else *out += ((r - *out) * a) >> 8; @@ -393,17 +402,23 @@ bool RenderedImage::blit(int posX, int posY, int flipping, Common::Rect *pPartRe #else *out = 255; out++; - if (cr != 255) + if (cr == 0) + *out = 0; + else if (cr != 255) *out += ((r - *out) * a * cr) >> 16; else *out += ((r - *out) * a) >> 8; out++; - if (cg != 255) + if (cg == 0) + *out = 0; + else if (cg != 255) *out += ((g - *out) * a * cg) >> 16; else *out += ((g - *out) * a) >> 8; out++; - if (cb != 255) + if (cb == 0) + *out = 0; + else if (cb != 255) *out += ((b - *out) * a * cb) >> 16; else *out += ((b - *out) * a) >> 8; diff --git a/engines/sword25/gfx/image/vectorimage.cpp b/engines/sword25/gfx/image/vectorimage.cpp index 9235ec2fcf..81f4fc2ad5 100644 --- a/engines/sword25/gfx/image/vectorimage.cpp +++ b/engines/sword25/gfx/image/vectorimage.cpp @@ -248,7 +248,7 @@ VectorImage::VectorImage(const byte *pFileData, uint fileSize, bool &success, co } // readout SWF size - Common::Rect movieRect = flashRectToBSRect(bs); + flashRectToBSRect(bs); // Get frame rate and frame count /* uint32 frameRate = */ @@ -321,6 +321,8 @@ ArtBpath *VectorImage::storeBez(ArtBpath *bez, int lineStyle, int fillStyle0, in bez[*bezNodes].code = ART_END; ArtBpath *bez1 = art_new(ArtBpath, *bezNodes + 1); + if (!bez1) + error("[VectorImage::storeBez] Cannot allocate memory"); for (int i = 0; i <= *bezNodes; i++) bez1[i] = bez[i]; diff --git a/engines/sword25/gfx/image/vectorimagerenderer.cpp b/engines/sword25/gfx/image/vectorimagerenderer.cpp index 97dad3346d..6d4dc213f2 100644 --- a/engines/sword25/gfx/image/vectorimagerenderer.cpp +++ b/engines/sword25/gfx/image/vectorimagerenderer.cpp @@ -270,6 +270,9 @@ ArtVpath *art_vpath_cat(ArtVpath *a, ArtVpath *b) { len_a = art_vpath_len(a); len_b = art_vpath_len(b); dest = art_new(ArtVpath, len_a + len_b + 1); + if (!dest) + error("[art_vpath_cat] Cannot allocate memory"); + p = dest; for (int i = 0; i < len_a; i++) @@ -299,6 +302,8 @@ ArtVpath *art_vpath_reverse(ArtVpath *a) { len = art_vpath_len(a); dest = art_new(ArtVpath, len + 1); + if (!dest) + error("[art_vpath_reverse] Cannot allocate memory"); for (i = 0; i < len; i++) { it = a[len - i - 1]; @@ -371,6 +376,8 @@ void drawBez(ArtBpath *bez1, ArtBpath *bez2, byte *buffer, int width, int height int size = art_vpath_len(vec); ArtVpath *vect = art_new(ArtVpath, size + 1); + if (!vect) + error("[drawBez] Cannot allocate memory"); int k; for (k = 0; k < size; k++) { diff --git a/engines/sword25/gfx/screenshot.cpp b/engines/sword25/gfx/screenshot.cpp index 4f9ba1d3c5..de7b62fba9 100644 --- a/engines/sword25/gfx/screenshot.cpp +++ b/engines/sword25/gfx/screenshot.cpp @@ -67,8 +67,8 @@ bool Screenshot::saveToFile(Graphics::Surface *data, Common::WriteStream *stream Common::SeekableReadStream *Screenshot::createThumbnail(Graphics::Surface *data) { // This method takes a screen image with a dimension of 800x600, and creates a screenshot with a dimension of 200x125. - // First 50 pixels are cut off the top and bottom (the interface boards in the game). The remaining image of 800x500 - // will be on a 16th of its size, reduced by being handed out in 4x4 pixel blocks and the average of each block + // First 50 pixels are cut off the top and bottom (the interface boards in the game). The remaining image of 800x500 + // will be on a 16th of its size, reduced by being handed out in 4x4 pixel blocks and the average of each block // generates a pixel of the target image. Finally, the result as a PNG file is stored as a file. // The source image must be 800x600. @@ -84,7 +84,7 @@ Common::SeekableReadStream *Screenshot::createThumbnail(Graphics::Surface *data) // Über das Zielbild iterieren und einen Pixel zur Zeit berechnen. uint x, y; x = y = 0; - + for (byte *pDest = (byte *)thumbnail.pixels; pDest < ((byte *)thumbnail.pixels + thumbnail.pitch * thumbnail.h); ) { // Get an average over a 4x4 pixel block in the source image int alpha, red, green, blue; diff --git a/engines/sword25/gfx/staticbitmap.cpp b/engines/sword25/gfx/staticbitmap.cpp index 60ad94e20f..0ae07b36b5 100644 --- a/engines/sword25/gfx/staticbitmap.cpp +++ b/engines/sword25/gfx/staticbitmap.cpp @@ -170,7 +170,10 @@ bool StaticBitmap::unpersist(InputPersistenceBlock &reader) { result &= Bitmap::unpersist(reader); Common::String resourceFilename; reader.readString(resourceFilename); - result &= initBitmapResource(resourceFilename); + // We may not have saves, and we actually do not need to + // restore them. So do not even try to load them. + if (!resourceFilename.hasPrefix("/saves")) + result &= initBitmapResource(resourceFilename); result &= RenderObject::unpersistChildren(reader); diff --git a/engines/sword25/gfx/text.cpp b/engines/sword25/gfx/text.cpp index 8e18d2936d..82bb7cdff7 100644 --- a/engines/sword25/gfx/text.cpp +++ b/engines/sword25/gfx/text.cpp @@ -61,7 +61,7 @@ Text::Text(InputPersistenceBlock &reader, RenderObjectPtr<RenderObject> parentPt // Temporarily set fields prior to unpersisting actual values _modulationColor(0xffffffff), _autoWrap(false), - _autoWrapThreshold(AUTO_WRAP_THRESHOLD_DEFAULT) { + _autoWrapThreshold(AUTO_WRAP_THRESHOLD_DEFAULT) { // Unpersist the fields _initSuccess = unpersist(reader); diff --git a/engines/sword25/kernel/inputpersistenceblock.cpp b/engines/sword25/kernel/inputpersistenceblock.cpp index c1cd771e39..cdce539c31 100644 --- a/engines/sword25/kernel/inputpersistenceblock.cpp +++ b/engines/sword25/kernel/inputpersistenceblock.cpp @@ -35,9 +35,10 @@ namespace Sword25 { -InputPersistenceBlock::InputPersistenceBlock(const void *data, uint dataLength) : +InputPersistenceBlock::InputPersistenceBlock(const void *data, uint dataLength, int version) : _data(static_cast<const byte *>(data), dataLength), - _errorState(NONE) { + _errorState(NONE), + _version(version) { _iter = _data.begin(); } @@ -54,8 +55,8 @@ void InputPersistenceBlock::read(int16 &value) { void InputPersistenceBlock::read(signed int &value) { if (checkMarker(SINT_MARKER)) { - rawRead(&value, sizeof(signed int)); - value = convertEndianessFromStorageToSystem(value); + value = (int32)READ_LE_UINT32(_iter); + _iter += 4; } else { value = 0; } @@ -63,8 +64,8 @@ void InputPersistenceBlock::read(signed int &value) { void InputPersistenceBlock::read(uint &value) { if (checkMarker(UINT_MARKER)) { - rawRead(&value, sizeof(uint)); - value = convertEndianessFromStorageToSystem(value); + value = READ_LE_UINT32(_iter); + _iter += 4; } else { value = 0; } @@ -72,8 +73,10 @@ void InputPersistenceBlock::read(uint &value) { void InputPersistenceBlock::read(float &value) { if (checkMarker(FLOAT_MARKER)) { - rawRead(&value, sizeof(float)); - value = convertEndianessFromStorageToSystem(value); + uint32 tmp[1]; + tmp[0] = READ_LE_UINT32(_iter); + value = ((float *)tmp)[0]; + _iter += 4; } else { value = 0.0f; } @@ -81,12 +84,11 @@ void InputPersistenceBlock::read(float &value) { void InputPersistenceBlock::read(bool &value) { if (checkMarker(BOOL_MARKER)) { - uint uintBool; - rawRead(&uintBool, sizeof(float)); - uintBool = convertEndianessFromStorageToSystem(uintBool); + uint uintBool = READ_LE_UINT32(_iter); + _iter += 4; value = uintBool == 0 ? false : true; } else { - value = 0.0f; + value = false; } } @@ -116,13 +118,6 @@ void InputPersistenceBlock::readByteArray(Common::Array<byte> &value) { } } -void InputPersistenceBlock::rawRead(void *destPtr, size_t size) { - if (checkBlockSize(size)) { - memcpy(destPtr, &*_iter, size); - _iter += size; - } -} - bool InputPersistenceBlock::checkBlockSize(int size) { if (_data.end() - _iter >= size) { return true; diff --git a/engines/sword25/kernel/inputpersistenceblock.h b/engines/sword25/kernel/inputpersistenceblock.h index f643b06bc1..2518d7e32c 100644 --- a/engines/sword25/kernel/inputpersistenceblock.h +++ b/engines/sword25/kernel/inputpersistenceblock.h @@ -46,7 +46,7 @@ public: OUT_OF_SYNC }; - InputPersistenceBlock(const void *data, uint dataLength); + InputPersistenceBlock(const void *data, uint dataLength, int version); virtual ~InputPersistenceBlock(); void read(int16 &value); @@ -64,14 +64,17 @@ public: return _errorState; } + int getVersion() const { return _version; } + private: bool checkMarker(byte marker); bool checkBlockSize(int size); - void rawRead(void *destPtr, size_t size); Common::Array<byte> _data; Common::Array<byte>::const_iterator _iter; ErrorState _errorState; + + int _version; }; } // End of namespace Sword25 diff --git a/engines/sword25/kernel/outputpersistenceblock.cpp b/engines/sword25/kernel/outputpersistenceblock.cpp index cf28ea401f..e29d956e5f 100644 --- a/engines/sword25/kernel/outputpersistenceblock.cpp +++ b/engines/sword25/kernel/outputpersistenceblock.cpp @@ -43,19 +43,23 @@ OutputPersistenceBlock::OutputPersistenceBlock() { void OutputPersistenceBlock::write(signed int value) { writeMarker(SINT_MARKER); - value = convertEndianessFromSystemToStorage(value); + value = TO_LE_32(value); rawWrite(&value, sizeof(value)); } void OutputPersistenceBlock::write(uint value) { writeMarker(UINT_MARKER); - value = convertEndianessFromSystemToStorage(value); + value = TO_LE_32(value); rawWrite(&value, sizeof(value)); } void OutputPersistenceBlock::write(float value) { writeMarker(FLOAT_MARKER); - value = convertEndianessFromSystemToStorage(value); + uint32 tmp[1]; + + ((float *)tmp)[0] = value; + tmp[0] = TO_LE_32(tmp[0]); + rawWrite(&value, sizeof(value)); } @@ -63,7 +67,7 @@ void OutputPersistenceBlock::write(bool value) { writeMarker(BOOL_MARKER); uint uintBool = value ? 1 : 0; - uintBool = convertEndianessFromSystemToStorage(uintBool); + uintBool = TO_LE_32(uintBool); rawWrite(&uintBool, sizeof(uintBool)); } diff --git a/engines/sword25/kernel/persistenceblock.h b/engines/sword25/kernel/persistenceblock.h index d8440faa50..8ac3e84a41 100644 --- a/engines/sword25/kernel/persistenceblock.h +++ b/engines/sword25/kernel/persistenceblock.h @@ -64,48 +64,6 @@ protected: BLOCK_MARKER }; - // ----------------------------------------------------------------------------- - // Endianess Conversions - // ----------------------------------------------------------------------------- - // - // Everything is stored in Little Endian - // Big Endian Systems will need to be byte swapped during both saving and reading of saved values - // - - template<typename T> - static T convertEndianessFromSystemToStorage(T value) { - if (isBigEndian()) - reverseByteOrder(&value); - return value; - } - - template<typename T> - static T convertEndianessFromStorageToSystem(T value) { - if (isBigEndian()) - reverseByteOrder(&value); - return value; - } - -private: - static bool isBigEndian() { - uint dummy = 1; - byte *dummyPtr = reinterpret_cast<byte *>(&dummy); - return dummyPtr[0] == 0; - } - - template<typename T> - static void swap(T &one, T &two) { - T temp = one; - one = two; - two = temp; - } - - static void reverseByteOrder(void *ptr) { - // Reverses the byte order of the 32-bit word pointed to by Ptr - byte *charPtr = static_cast<byte *>(ptr); - swap(charPtr[0], charPtr[3]); - swap(charPtr[1], charPtr[2]); - } }; #define CTASSERT(ex) typedef char ctassert_type[(ex) ? 1 : -1] diff --git a/engines/sword25/kernel/persistenceservice.cpp b/engines/sword25/kernel/persistenceservice.cpp index 17e9199b5c..27d669caa1 100644 --- a/engines/sword25/kernel/persistenceservice.cpp +++ b/engines/sword25/kernel/persistenceservice.cpp @@ -50,7 +50,9 @@ static const char *SAVEGAME_DIRECTORY = "saves"; static const char *FILE_MARKER = "BS25SAVEGAME"; static const uint SLOT_COUNT = 18; static const uint FILE_COPY_BUFFER_SIZE = 1024 * 10; -static const char *VERSIONID = "SCUMMVM1"; +static const char *VERSIONIDOLD = "SCUMMVM1"; +static const char *VERSIONID = "SCUMMVM2"; +static const int VERSIONNUM = 2; #define MAX_SAVEGAME_SIZE 100 @@ -99,6 +101,7 @@ struct SavegameInformation { bool isOccupied; bool isCompatible; Common::String description; + int version; uint gamedataLength; uint gamedataOffset; uint gamedataUncompressedLength; @@ -147,9 +150,15 @@ struct PersistenceService::Impl { // Read in the header Common::String storedMarker = loadString(file); Common::String storedVersionID = loadString(file); + if (storedVersionID == VERSIONIDOLD) { + curSavegameInfo.version = 1; + } else { + Common::String versionNum = loadString(file); + curSavegameInfo.version = atoi(versionNum.c_str()); + } Common::String gameDescription = loadString(file); - Common::String gameDataLength = loadString(file); - curSavegameInfo.gamedataLength = atoi(gameDataLength.c_str()); + Common::String gamedataLength = loadString(file); + curSavegameInfo.gamedataLength = atoi(gamedataLength.c_str()); Common::String gamedataUncompressedLength = loadString(file); curSavegameInfo.gamedataUncompressedLength = atoi(gamedataUncompressedLength.c_str()); @@ -158,7 +167,7 @@ struct PersistenceService::Impl { // The slot is marked as occupied. curSavegameInfo.isOccupied = true; // Check if the saved game is compatible with the current engine version. - curSavegameInfo.isCompatible = (storedVersionID == Common::String(VERSIONID)); + curSavegameInfo.isCompatible = (curSavegameInfo.version <= VERSIONNUM); // Load the save game description. curSavegameInfo.description = gameDescription; // The offset to the stored save game data within the file. @@ -199,7 +208,7 @@ Common::String PersistenceService::getSavegameDirectory() { // Try and return the path using the savegame subfolder. But if doesn't exist, fall back on the data directory if (childNode.exists()) return childNode.getPath(); - + return node.getPath(); } @@ -242,6 +251,12 @@ Common::String &PersistenceService::getSavegameFilename(uint slotID) { return result; } +int PersistenceService::getSavegameVersion(uint slotID) { + if (!checkslotID(slotID)) + return -1; + return _impl->_savegameInformations[slotID].version; +} + bool PersistenceService::saveGame(uint slotID, const Common::String &screenshotFilename) { // FIXME: This code is a hack which bypasses the savefile API, // and should eventually be removed. @@ -264,6 +279,11 @@ bool PersistenceService::saveGame(uint slotID, const Common::String &screenshotF file->writeString(VERSIONID); file->writeByte(0); + char buf[20]; + snprintf(buf, 20, "%d", VERSIONNUM); + file->writeString(buf); + file->writeByte(0); + TimeDate dt; g_system->getTimeAndDate(dt); file->writeString(formatTimestamp(dt)); @@ -385,7 +405,7 @@ bool PersistenceService::loadGame(uint slotID) { memcpy(uncompressedDataBuffer, compressedDataBuffer, uncompressedBufferSize); } - InputPersistenceBlock reader(&uncompressedDataBuffer[0], curSavegameInfo.gamedataUncompressedLength); + InputPersistenceBlock reader(&uncompressedDataBuffer[0], curSavegameInfo.gamedataUncompressedLength, curSavegameInfo.version); // Einzelne Engine-Module depersistieren. bool success = true; diff --git a/engines/sword25/kernel/persistenceservice.h b/engines/sword25/kernel/persistenceservice.h index f73962892c..59e0a3661d 100644 --- a/engines/sword25/kernel/persistenceservice.h +++ b/engines/sword25/kernel/persistenceservice.h @@ -57,6 +57,7 @@ public: void reloadSlots(); bool isSlotOccupied(uint slotID); bool isSavegameCompatible(uint slotID); + int getSavegameVersion(uint slotID); Common::String &getSavegameDescription(uint slotID); Common::String &getSavegameFilename(uint slotID); diff --git a/engines/sword25/math/regionregistry.cpp b/engines/sword25/math/regionregistry.cpp index dff8560205..68c360a5ee 100644 --- a/engines/sword25/math/regionregistry.cpp +++ b/engines/sword25/math/regionregistry.cpp @@ -34,7 +34,9 @@ #include "sword25/math/regionregistry.h" #include "sword25/math/region.h" +namespace Common { DECLARE_SINGLETON(Sword25::RegionRegistry); +} namespace Sword25 { diff --git a/engines/sword25/package/packagemanager.cpp b/engines/sword25/package/packagemanager.cpp index 5c869203c6..5549f50c3c 100644 --- a/engines/sword25/package/packagemanager.cpp +++ b/engines/sword25/package/packagemanager.cpp @@ -157,7 +157,7 @@ byte *PackageManager::getFile(const Common::String &fileName, uint *fileSizePtr) byte *buffer = new byte[file->size()]; file->read(buffer, file->size()); - + delete file; return buffer; } diff --git a/engines/sword25/package/packagemanager.h b/engines/sword25/package/packagemanager.h index 3c4c4e89c5..b0c6718008 100644 --- a/engines/sword25/package/packagemanager.h +++ b/engines/sword25/package/packagemanager.h @@ -141,6 +141,9 @@ public: uint fileSize; char *data = (char *)getFile(fileName, &fileSize); char *result = (char *)malloc(fileSize + strlen(versionStr) + 1); + if (!result) + error("[PackageManager::getXmlFile] Cannot allocate memory"); + strcpy(result, versionStr); Common::copy(data, data + fileSize, result + strlen(versionStr)); result[fileSize + strlen(versionStr)] = '\0'; @@ -151,7 +154,7 @@ public: return result; } - + /** * Returns the path to the current directory. * @return Returns a string containing the path to the current directory. diff --git a/engines/sword25/sfx/soundengine.cpp b/engines/sword25/sfx/soundengine.cpp index 9244137c25..1b424dac65 100644 --- a/engines/sword25/sfx/soundengine.cpp +++ b/engines/sword25/sfx/soundengine.cpp @@ -33,6 +33,8 @@ #include "sword25/sfx/soundengine.h" #include "sword25/package/packagemanager.h" #include "sword25/kernel/resource.h" +#include "sword25/kernel/inputpersistenceblock.h" +#include "sword25/kernel/outputpersistenceblock.h" #include "audio/decoders/vorbis.h" @@ -61,6 +63,8 @@ SoundEngine::SoundEngine(Kernel *pKernel) : ResourceService(pKernel) { _mixer = g_system->getMixer(); + _maxHandleId = 1; + for (int i = 0; i < SOUND_HANDLES; i++) _handles[i].type = kFreeHandle; } @@ -139,19 +143,24 @@ void SoundEngine::resumeLayer(uint layer) { SndHandle *SoundEngine::getHandle(uint *id) { - // NOTE: Index 0 means error. Thus we're not using it - for (uint i = 1; i < SOUND_HANDLES; i++) { + for (uint i = 0; i < SOUND_HANDLES; i++) { if (_handles[i].type != kFreeHandle && !_mixer->isSoundHandleActive(_handles[i].handle)) { - debugC(kDebugSound, 5, "Handle %d has finished playing", i); + debugC(1, kDebugSound, "Handle %d has finished playing", _handles[i].id); _handles[i].type = kFreeHandle; } } - for (uint i = 1; i < SOUND_HANDLES; i++) { + for (uint i = 0; i < SOUND_HANDLES; i++) { if (_handles[i].type == kFreeHandle) { - debugC(kDebugSound, 5, "Allocated handle %d", i); + debugC(1, kDebugSound, "Allocated handle %d", _handles[i].id); + _handles[i].id = _maxHandleId; + _handles[i].type = kAllocatedHandle; + if (id) - *id = i; + *id = _maxHandleId; + + _maxHandleId++; + return &_handles[i]; } } @@ -161,6 +170,17 @@ SndHandle *SoundEngine::getHandle(uint *id) { return NULL; } +SndHandle *SoundEngine::findHandle(uint id) { + for (uint i = 0; i < SOUND_HANDLES; i++) { + if (_handles[i].id == id) + return &_handles[i]; + } + + warning("Sound::findHandle(): Unknown handle"); + + return NULL; +} + Audio::Mixer::SoundType getType(SoundEngine::SOUND_TYPES type) { switch (type) { case SoundEngine::MUSIC: @@ -184,13 +204,27 @@ bool SoundEngine::playSound(const Common::String &fileName, SOUND_TYPES type, fl return true; } -uint SoundEngine::playSoundEx(const Common::String &fileName, SOUND_TYPES type, float volume, float pan, bool loop, int loopStart, int loopEnd, uint layer) { +uint SoundEngine::playSoundEx(const Common::String &fileName, SOUND_TYPES type, float volume, float pan, bool loop, int loopStart, int loopEnd, uint layer, uint handleId) { Common::SeekableReadStream *in = Kernel::getInstance()->getPackage()->getStream(fileName); #ifdef USE_VORBIS Audio::SeekableAudioStream *stream = Audio::makeVorbisStream(in, DisposeAfterUse::YES); #endif uint id; - SndHandle *handle = getHandle(&id); + SndHandle *handle; + + if (handleId == 0x1337) + handle = getHandle(&id); + else + handle = &_handles[handleId]; + + handle->fileName = fileName; + handle->sndType = type; + handle->volume = volume; + handle->pan = pan; + handle->loop = loop; + handle->loopStart = loopStart; + handle->loopEnd = loopEnd; + handle->layer = layer; debugC(1, kDebugSound, "SoundEngine::playSoundEx(%s, %d, %f, %f, %d, %d, %d, %d)", fileName.c_str(), type, volume, pan, loop, loopStart, loopEnd, layer); @@ -202,43 +236,43 @@ uint SoundEngine::playSoundEx(const Common::String &fileName, SOUND_TYPES type, } void SoundEngine::setSoundVolume(uint handle, float volume) { - assert(handle < SOUND_HANDLES); - debugC(1, kDebugSound, "SoundEngine::setSoundVolume(%d, %f)", handle, volume); - _mixer->setChannelVolume(_handles[handle].handle, (byte)(volume * 255)); + SndHandle* sndHandle = findHandle(handle); + if (sndHandle != NULL) + _mixer->setChannelVolume(sndHandle->handle, (byte)(volume * 255)); } void SoundEngine::setSoundPanning(uint handle, float pan) { - assert(handle < SOUND_HANDLES); - debugC(1, kDebugSound, "SoundEngine::setSoundPanning(%d, %f)", handle, pan); - _mixer->setChannelBalance(_handles[handle].handle, (int8)(pan * 127)); + SndHandle* sndHandle = findHandle(handle); + if (sndHandle != NULL) + _mixer->setChannelBalance(sndHandle->handle, (int8)(pan * 127)); } void SoundEngine::pauseSound(uint handle) { - assert(handle < SOUND_HANDLES); - debugC(1, kDebugSound, "SoundEngine::pauseSound(%d)", handle); - _mixer->pauseHandle(_handles[handle].handle, true); + SndHandle* sndHandle = findHandle(handle); + if (sndHandle != NULL) + _mixer->pauseHandle(sndHandle->handle, true); } void SoundEngine::resumeSound(uint handle) { - assert(handle < SOUND_HANDLES); - debugC(1, kDebugSound, "SoundEngine::resumeSound(%d)", handle); - _mixer->pauseHandle(_handles[handle].handle, false); + SndHandle* sndHandle = findHandle(handle); + if (sndHandle != NULL) + _mixer->pauseHandle(sndHandle->handle, false); } void SoundEngine::stopSound(uint handle) { - assert(handle < SOUND_HANDLES); - debugC(1, kDebugSound, "SoundEngine::stopSound(%d)", handle); - _mixer->stopHandle(_handles[handle].handle); + SndHandle* sndHandle = findHandle(handle); + if (sndHandle != NULL) + _mixer->stopHandle(sndHandle->handle); } bool SoundEngine::isSoundPaused(uint handle) { @@ -250,23 +284,30 @@ bool SoundEngine::isSoundPaused(uint handle) { } bool SoundEngine::isSoundPlaying(uint handle) { - assert(handle < SOUND_HANDLES); - debugC(1, kDebugSound, "SoundEngine::isSoundPlaying(%d)", handle); - return _mixer->isSoundHandleActive(_handles[handle].handle); + SndHandle* sndHandle = findHandle(handle); + if (sndHandle == NULL) + return false; + return _mixer->isSoundHandleActive(sndHandle->handle); } float SoundEngine::getSoundVolume(uint handle) { debugC(1, kDebugSound, "SoundEngine::getSoundVolume(%d)", handle); - return (float)_mixer->getChannelVolume(_handles[handle].handle) / 255.0; + SndHandle* sndHandle = findHandle(handle); + if (sndHandle == NULL) + return 0.f; + return (float)_mixer->getChannelVolume(sndHandle->handle) / 255.0; } float SoundEngine::getSoundPanning(uint handle) { debugC(1, kDebugSound, "SoundEngine::getSoundPanning(%d)", handle); - return (float)_mixer->getChannelBalance(_handles[handle].handle) / 127.0; + SndHandle* sndHandle = findHandle(handle); + if (sndHandle == NULL) + return 0.f; + return (float)_mixer->getChannelBalance(sndHandle->handle) / 127.0; } Resource *SoundEngine::loadResource(const Common::String &fileName) { @@ -284,16 +325,61 @@ bool SoundEngine::canLoadResource(const Common::String &fileName) { } -bool SoundEngine::persist(OutputPersistenceBlock &writer) { - warning("STUB: SoundEngine::persist()"); + bool SoundEngine::persist(OutputPersistenceBlock &writer) { + writer.write(_maxHandleId); + + for (uint i = 0; i < SOUND_HANDLES; i++) { + writer.write(_handles[i].id); + + writer.writeString(_handles[i].fileName); + writer.write((int)_handles[i].sndType); + writer.write(_handles[i].volume); + writer.write(_handles[i].pan); + writer.write(_handles[i].loop); + writer.write(_handles[i].loopStart); + writer.write(_handles[i].loopEnd); + writer.write(_handles[i].layer); + } return true; } bool SoundEngine::unpersist(InputPersistenceBlock &reader) { - warning("STUB: SoundEngine::unpersist()"); + _mixer->stopAll(); + + if (reader.getVersion() < 2) + return true; + + reader.read(_maxHandleId); + + for (uint i = 0; i < SOUND_HANDLES; i++) { + reader.read(_handles[i].id); + + Common::String fileName; + int sndType; + float volume; + float pan; + bool loop; + int loopStart; + int loopEnd; + uint layer; + + reader.readString(fileName); + reader.read(sndType); + reader.read(volume); + reader.read(pan); + reader.read(loop); + reader.read(loopStart); + reader.read(loopEnd); + reader.read(layer); + + if (reader.isGood()) { + playSoundEx(fileName, (SOUND_TYPES)sndType, volume, pan, loop, loopStart, loopEnd, layer, i); + } else + return false; + } - return true; + return reader.isGood(); } diff --git a/engines/sword25/sfx/soundengine.h b/engines/sword25/sfx/soundengine.h index 4dbd475846..8132ec556e 100644 --- a/engines/sword25/sfx/soundengine.h +++ b/engines/sword25/sfx/soundengine.h @@ -58,13 +58,22 @@ namespace Sword25 { enum sndHandleType { kFreeHandle, - kEffectHandle, - kVoiceHandle + kAllocatedHandle }; struct SndHandle { Audio::SoundHandle handle; sndHandleType type; + uint32 id; + + Common::String fileName; + int sndType; + float volume; + float pan; + bool loop; + int loopStart; + int loopEnd; + uint layer; }; @@ -176,7 +185,7 @@ public: * @remark If more control is needed over the playing, eg. changing the sound parameters * for Volume and Panning, then PlaySoundEx should be used. */ - uint playSoundEx(const Common::String &fileName, SOUND_TYPES type, float volume = 1.0f, float pan = 0.0f, bool loop = false, int loopStart = -1, int loopEnd = -1, uint layer = 0); + uint playSoundEx(const Common::String &fileName, SOUND_TYPES type, float volume = 1.0f, float pan = 0.0f, bool loop = false, int loopStart = -1, int loopEnd = -1, uint layer = 0, uint handleId = 0x1337); /** * Sets the volume of a playing sound @@ -244,10 +253,13 @@ public: private: bool registerScriptBindings(); SndHandle *getHandle(uint *id); + SndHandle *findHandle(uint id); private: Audio::Mixer *_mixer; SndHandle _handles[SOUND_HANDLES]; + + uint32 _maxHandleId; }; } // End of namespace Sword25 diff --git a/engines/sword25/sword25.cpp b/engines/sword25/sword25.cpp index b111746c32..2201188052 100644 --- a/engines/sword25/sword25.cpp +++ b/engines/sword25/sword25.cpp @@ -50,7 +50,9 @@ #include "sword25/gfx/animationtemplateregistry.h" // Needed so we can destroy the singleton #include "sword25/gfx/renderobjectregistry.h" // Needed so we can destroy the singleton +namespace Common { DECLARE_SINGLETON(Sword25::RenderObjectRegistry); +} #include "sword25/math/regionregistry.h" // Needed so we can destroy the singleton namespace Sword25 { diff --git a/engines/sword25/util/lua/lapi.cpp b/engines/sword25/util/lua/lapi.cpp index 16f8460e39..ff25cfc653 100644 --- a/engines/sword25/util/lua/lapi.cpp +++ b/engines/sword25/util/lua/lapi.cpp @@ -213,7 +213,7 @@ LUA_API void lua_replace (lua_State *L, int idx) { api_checkvalidindex(L, o); if (idx == LUA_ENVIRONINDEX) { Closure *func = curr_func(L); - api_check(L, ttistable(L->top - 1)); + api_check(L, ttistable(L->top - 1)); func->c.env = hvalue(L->top - 1); luaC_barrier(L, func, L->top - 1); } @@ -773,7 +773,7 @@ LUA_API int lua_setfenv (lua_State *L, int idx) { #define checkresults(L,na,nr) \ api_check(L, (nr) == LUA_MULTRET || (L->ci->top - L->top >= (nr) - (na))) - + LUA_API void lua_call (lua_State *L, int nargs, int nresults) { StkId func; diff --git a/engines/sword25/util/lua/lauxlib.cpp b/engines/sword25/util/lua/lauxlib.cpp index 8978cd5613..1261777315 100644 --- a/engines/sword25/util/lua/lauxlib.cpp +++ b/engines/sword25/util/lua/lauxlib.cpp @@ -570,13 +570,13 @@ LUALIB_API int luaL_loadfile (lua_State *L, const char *filename) { } c = lf.f->getc(); - if (c == '#') { // Unix exec. file? + if (c == '#') { // Unix exec. file? lf.extraline = 1; - while ((c = lf.f->getc()) != EOF && c != '\n') ; // skip first line + 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 = lf.f->getc()) != EOF && c != LUA_SIGNATURE[0]) ; diff --git a/engines/sword25/util/lua/ldblib.cpp b/engines/sword25/util/lua/ldblib.cpp index 4d0333b46e..618e9a843f 100644 --- a/engines/sword25/util/lua/ldblib.cpp +++ b/engines/sword25/util/lua/ldblib.cpp @@ -142,7 +142,7 @@ static int db_getinfo (lua_State *L) { treatstackoption(L, L1, "func"); return 1; /* return table */ } - + static int db_getlocal (lua_State *L) { int arg; diff --git a/engines/sword25/util/lua/ldebug.cpp b/engines/sword25/util/lua/ldebug.cpp index 0b26522b31..85c492cc77 100644 --- a/engines/sword25/util/lua/ldebug.cpp +++ b/engines/sword25/util/lua/ldebug.cpp @@ -184,7 +184,7 @@ static void collectvalidlines (lua_State *L, Closure *f) { int i; for (i=0; i<f->l.p->sizelineinfo; i++) setbvalue(luaH_setnum(L, t, lineinfo[i]), 1); - sethvalue(L, L->top, t); + sethvalue(L, L->top, t); } incr_top(L); } diff --git a/engines/sword25/util/lua/ldo.cpp b/engines/sword25/util/lua/ldo.cpp index bbcdf98b3d..49e0881a45 100644 --- a/engines/sword25/util/lua/ldo.cpp +++ b/engines/sword25/util/lua/ldo.cpp @@ -384,7 +384,7 @@ int luaD_poscall (lua_State *L, StkId firstResult) { ** The arguments are on the stack, right after the function. ** When returns, all the results are on the stack, starting at the original ** function position. -*/ +*/ void luaD_call (lua_State *L, StkId func, int nResults) { if (++L->nCcalls >= LUAI_MAXCCALLS) { if (L->nCcalls == LUAI_MAXCCALLS) diff --git a/engines/sword25/util/lua/lgc.cpp b/engines/sword25/util/lua/lgc.cpp index 52ff72bdc9..71e581ad30 100644 --- a/engines/sword25/util/lua/lgc.cpp +++ b/engines/sword25/util/lua/lgc.cpp @@ -310,7 +310,7 @@ static l_mem propagatemark (global_State *g) { traverseproto(g, p); return sizeof(Proto) + sizeof(Instruction) * p->sizecode + sizeof(Proto *) * p->sizep + - sizeof(TValue) * p->sizek + + sizeof(TValue) * p->sizek + sizeof(int) * p->sizelineinfo + sizeof(LocVar) * p->sizelocvars + sizeof(TString *) * p->sizeupvalues; @@ -697,7 +697,7 @@ void luaC_linkupval (lua_State *L, UpVal *uv) { GCObject *o = obj2gco(uv); o->gch.next = g->rootgc; /* link upvalue into `rootgc' list */ g->rootgc = o; - if (isgray(o)) { + if (isgray(o)) { if (g->gcstate == GCSpropagate) { gray2black(o); /* closed upvalues need barrier */ luaC_barrier(L, uv, uv->v); diff --git a/engines/sword25/util/lua/liolib.cpp b/engines/sword25/util/lua/liolib.cpp index b505d1e4df..6c00de5094 100644 --- a/engines/sword25/util/lua/liolib.cpp +++ b/engines/sword25/util/lua/liolib.cpp @@ -228,7 +228,7 @@ static int g_iofile (lua_State *L, int f, const char *mode) { } lua_rawseti(L, LUA_ENVIRONINDEX, f); } - // return current value + // return current value lua_rawgeti(L, LUA_ENVIRONINDEX, f); return 1; } @@ -315,7 +315,7 @@ static int read_line (lua_State *L, Sword25::Sword25FileProxy *f) { for (;;) { size_t l; char *p = luaL_prepbuffer(&b); - if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { // eof? + if (fgets(p, LUAL_BUFFERSIZE, f) == NULL) { // eof? luaL_pushresult(&b); // close buffer return (lua_objlen(L, -1) > 0); // check whether read something } @@ -332,19 +332,19 @@ static int read_line (lua_State *L, Sword25::Sword25FileProxy *f) { 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 + 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); } @@ -354,11 +354,11 @@ static int g_read (lua_State *L, Sword25::Sword25FileProxy *f, int first) { 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++) { @@ -370,15 +370,15 @@ static int g_read (lua_State *L, Sword25::Sword25FileProxy *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"); @@ -389,8 +389,8 @@ static int g_read (lua_State *L, Sword25::Sword25FileProxy *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; } @@ -419,8 +419,8 @@ static int io_readline (lua_State *L) { 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 diff --git a/engines/sword25/util/lua/llex.cpp b/engines/sword25/util/lua/llex.cpp index 4d73a6a600..b456ee2dfe 100644 --- a/engines/sword25/util/lua/llex.cpp +++ b/engines/sword25/util/lua/llex.cpp @@ -188,7 +188,7 @@ static void trydecpoint (LexState *ls, SemInfo *seminfo) { sprintf(buf, "%.1f", 1.0); ls->decpoint = '.'; for (i = 0; buf[i]; i++) { - if (!isspace(buf[i]) && !isdigit(buf[i])) { + if (!isspace(static_cast<unsigned char>(buf[i])) && !isdigit(static_cast<unsigned char>(buf[i]))) { ls->decpoint = buf[i]; break; } diff --git a/engines/sword25/util/lua/llimits.h b/engines/sword25/util/lua/llimits.h index a31ad160ad..0925231350 100644 --- a/engines/sword25/util/lua/llimits.h +++ b/engines/sword25/util/lua/llimits.h @@ -107,7 +107,7 @@ typedef lu_int32 Instruction; #ifndef lua_lock -#define lua_lock(L) ((void) 0) +#define lua_lock(L) ((void) 0) #define lua_unlock(L) ((void) 0) #endif @@ -118,7 +118,7 @@ typedef lu_int32 Instruction; /* ** macro to control inclusion of some hard tests on stack reallocation -*/ +*/ #ifndef HARDSTACKTESTS #define condhardstacktests(x) ((void)0) #else diff --git a/engines/sword25/util/lua/loadlib.cpp b/engines/sword25/util/lua/loadlib.cpp index 9795a575f5..f4cdd70a78 100644 --- a/engines/sword25/util/lua/loadlib.cpp +++ b/engines/sword25/util/lua/loadlib.cpp @@ -182,7 +182,7 @@ static int ll_require (lua_State *L) { ** 'module' function ** ======================================================= */ - + static void setfenv (lua_State *L) { lua_Debug ar; @@ -298,7 +298,7 @@ LUALIB_API int luaopen_package (lua_State *L) { lua_setfield(L, -2, "__gc"); /* create `package' table */ luaL_register(L, LUA_LOADLIBNAME, pk_funcs); -#if defined(LUA_COMPAT_LOADLIB) +#if defined(LUA_COMPAT_LOADLIB) lua_getfield(L, -1, "loadlib"); lua_setfield(L, LUA_GLOBALSINDEX, "loadlib"); #endif diff --git a/engines/sword25/util/lua/lobject.h b/engines/sword25/util/lua/lobject.h index 35aaed028a..5418a918b1 100644 --- a/engines/sword25/util/lua/lobject.h +++ b/engines/sword25/util/lua/lobject.h @@ -337,7 +337,7 @@ typedef struct Node { typedef struct Table { CommonHeader; - lu_byte flags; /* 1<<p means tagmethod(p) is not present */ + lu_byte flags; /* 1<<p means tagmethod(p) is not present */ lu_byte lsizenode; /* log2 of size of `node' array */ struct Table *metatable; TValue *array; /* array part */ diff --git a/engines/sword25/util/lua/lopcodes.h b/engines/sword25/util/lua/lopcodes.h index e1aed0f637..2f850c4365 100644 --- a/engines/sword25/util/lua/lopcodes.h +++ b/engines/sword25/util/lua/lopcodes.h @@ -186,8 +186,8 @@ OP_EQ,/* A B C if ((RK(B) == RK(C)) ~= A) then pc++ */ OP_LT,/* A B C if ((RK(B) < RK(C)) ~= A) then pc++ */ OP_LE,/* A B C if ((RK(B) <= RK(C)) ~= A) then pc++ */ -OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ -OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ +OP_TEST,/* A C if not (R(A) <=> C) then pc++ */ +OP_TESTSET,/* A B C if (R(B) <=> C) then R(A) := R(B) else pc++ */ OP_CALL,/* A B C R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */ OP_TAILCALL,/* A B C return R(A)(R(A+1), ... ,R(A+B-1)) */ @@ -197,8 +197,8 @@ OP_FORLOOP,/* A sBx R(A)+=R(A+2); if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/ OP_FORPREP,/* A sBx R(A)-=R(A+2); pc+=sBx */ -OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); - if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */ +OP_TFORLOOP,/* A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); + if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++ */ OP_SETLIST,/* A B C R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B */ OP_CLOSE,/* A close all variables in the stack up to (>=) R(A)*/ @@ -240,7 +240,7 @@ OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg */ ** bits 4-5: B arg mode ** bit 6: instruction set register A ** bit 7: operator is a test -*/ +*/ enum OpArgMask { OpArgN, /* argument is not used */ diff --git a/engines/sword25/util/lua/lstate.cpp b/engines/sword25/util/lua/lstate.cpp index 495d75c8a6..e542bcbacc 100644 --- a/engines/sword25/util/lua/lstate.cpp +++ b/engines/sword25/util/lua/lstate.cpp @@ -36,7 +36,7 @@ typedef struct LG { lua_State l; global_State g; } LG; - + static void stack_init (lua_State *L1, lua_State *L) { diff --git a/engines/sword25/util/lua/lstrlib.cpp b/engines/sword25/util/lua/lstrlib.cpp index e5501b9b49..2a1b8690e2 100644 --- a/engines/sword25/util/lua/lstrlib.cpp +++ b/engines/sword25/util/lua/lstrlib.cpp @@ -635,7 +635,7 @@ static void add_value (MatchState *ms, luaL_Buffer *b, const char *s, lua_pushlstring(L, s, e - s); /* keep original text */ } else if (!lua_isstring(L, -1)) - luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); + luaL_error(L, "invalid replacement value (a %s)", luaL_typename(L, -1)); luaL_addvalue(b); /* add result to accumulator */ } diff --git a/engines/sword25/util/lua/ltable.cpp b/engines/sword25/util/lua/ltable.cpp index b2ec0e912a..45381fe673 100644 --- a/engines/sword25/util/lua/ltable.cpp +++ b/engines/sword25/util/lua/ltable.cpp @@ -48,7 +48,7 @@ #define hashpow2(t,n) (gnode(t, lmod((n), sizenode(t)))) - + #define hashstr(t,str) hashpow2(t, (str)->tsv.hash) #define hashboolean(t,p) hashpow2(t, p) @@ -303,7 +303,7 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) { if (nasize > oldasize) /* array part must grow? */ setarrayvector(L, t, nasize); /* create new hash part with appropriate size */ - setnodevector(L, t, nhsize); + setnodevector(L, t, nhsize); if (nasize < oldasize) { /* array part must shrink? */ t->sizearray = nasize; /* re-insert elements from vanishing slice */ @@ -392,11 +392,11 @@ static Node *getfreepos (Table *t) { /* -** inserts a new key into a hash table; first, check whether key's main -** position is free. If not, check whether colliding node is in its main -** position or not: if it is not, move colliding node to an empty place and -** put new key in its main position; otherwise (colliding node is in its main -** position), new key goes to an empty position. +** inserts a new key into a hash table; first, check whether key's main +** position is free. If not, check whether colliding node is in its main +** position or not: if it is not, move colliding node to an empty place and +** put new key in its main position; otherwise (colliding node is in its main +** position), new key goes to an empty position. */ static TValue *newkey (lua_State *L, Table *t, const TValue *key) { Node *mp = mainposition(t, key); diff --git a/engines/sword25/util/lua/lua.h b/engines/sword25/util/lua/lua.h index 417cdadf8b..08ad80d70f 100644 --- a/engines/sword25/util/lua/lua.h +++ b/engines/sword25/util/lua/lua.h @@ -247,7 +247,7 @@ LUA_API void lua_setallocf (lua_State *L, lua_Alloc f, void *ud); -/* +/* ** =============================================================== ** some useful macros ** =============================================================== diff --git a/engines/sword25/util/lua/lualib.h b/engines/sword25/util/lua/lualib.h index 33d4e314c2..830f6a0894 100644 --- a/engines/sword25/util/lua/lualib.h +++ b/engines/sword25/util/lua/lualib.h @@ -41,7 +41,7 @@ LUALIB_API int (luaopen_package) (lua_State *L); /* open all previous libraries */ -LUALIB_API void (luaL_openlibs) (lua_State *L); +LUALIB_API void (luaL_openlibs) (lua_State *L); diff --git a/engines/sword25/util/lua/lvm.cpp b/engines/sword25/util/lua/lvm.cpp index fb700c20a2..d0f2198651 100644 --- a/engines/sword25/util/lua/lvm.cpp +++ b/engines/sword25/util/lua/lvm.cpp @@ -125,7 +125,7 @@ void luaV_gettable (lua_State *L, const TValue *t, TValue *key, StkId val) { callTMres(L, val, tm, t, key); return; } - t = tm; /* else repeat with `tm' */ + t = tm; /* else repeat with `tm' */ } luaG_runerror(L, "loop in gettable"); } @@ -152,7 +152,7 @@ void luaV_settable (lua_State *L, const TValue *t, TValue *key, StkId val) { callTM(L, tm, t, key, val); return; } - t = tm; /* else repeat with `tm' */ + t = tm; /* else repeat with `tm' */ } luaG_runerror(L, "loop in settable"); } diff --git a/engines/sword25/util/lua/scummvm_file.cpp b/engines/sword25/util/lua/scummvm_file.cpp index 3c0377d0ee..33053a71cb 100644 --- a/engines/sword25/util/lua/scummvm_file.cpp +++ b/engines/sword25/util/lua/scummvm_file.cpp @@ -32,11 +32,30 @@ Sword25FileProxy::Sword25FileProxy(const Common::String &filename, const Common: setupConfigFile(); } +Common::String Sword25FileProxy::formatDouble(double value) { + // This is a bit hackish. The point of it is that it's important that + // we ignore the locale decimal mark and force it to be a point. If it + // would happen to be a comma instead, it seems that it's seen as two + // comma-separated integers rather than one floating-point value. Or + // something like that. + + bool negative = value < 0.0; + value = fabs(value); + double integerPart = floor(value); + double fractionalPart = (value - integerPart) * 1000000.0; + + Common::String out = Common::String::format("%.0f.%.0f", integerPart, fractionalPart); + if (negative) + out = "-" + out; + + return out; +} + 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"); + 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\ @@ -45,10 +64,13 @@ 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); +SFX_SOUND_VOLUME = %s\r\n\ +SFX_MUSIC_VOLUME = %s\r\n\ +SFX_SPEECH_VOLUME = %s\r\n", + getLanguage().c_str(), subtitles ? "true" : "false", + formatDouble(sfxVolume).c_str(), + formatDouble(musicVolume).c_str(), + formatDouble(speechVolume).c_str()); _readPos = 0; } @@ -76,14 +98,14 @@ size_t Sword25FileProxy::write(const char *ptr, size_t count) { // Legitimate data const char *p = strchr(ptr, '\n'); if (!p) p = ptr + strlen(ptr); - while ((*p == '\r') || (*p == '\n')) + while ((*p == '\r') || (*p == '\n')) ++p; _settings += Common::String(ptr, p - ptr); ptr = p; } - while ((*ptr == '\r') || (*ptr == '\n')) + while ((*ptr == '\r') || (*ptr == '\n')) ++ptr; } @@ -97,7 +119,7 @@ void Sword25FileProxy::writeSettings() { if ((*pSrc != '\r') && (*pSrc != '\n')) { const char *p = strchr(pSrc, '='); assert(p); - + // Get the setting name const char *pEnd = p - 1; while (*pEnd == ' ') @@ -110,10 +132,10 @@ void Sword25FileProxy::writeSettings() { ++pStart; pEnd = pStart + 1; - while ((*pEnd != '\r') && (*pEnd != '\n') && (*pEnd != '\0')) + 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; diff --git a/engines/sword25/util/lua/scummvm_file.h b/engines/sword25/util/lua/scummvm_file.h index a4cbd2a6cf..e8c468ee07 100644 --- a/engines/sword25/util/lua/scummvm_file.h +++ b/engines/sword25/util/lua/scummvm_file.h @@ -37,6 +37,7 @@ private: uint _readPos; Common::String _settings; + Common::String formatDouble(double value); void setupConfigFile(); Common::String getLanguage(); void setLanguage(const Common::String &lang); |